在文件范围内修改的头文件中的C类型定义。

时间:2021-01-29 15:06:15

I need to include some typedef definition in two source files:

我需要在两个源文件中包含一些typedef定义:

typedef double mat[MATSIZE][MATSIZE] ;

so I created def.h which includes:

所以我创建了def.h,其中包括:

#ifndef DEF_H
#define DEF_H
typedef double mat[MATSIZE][MATSIZE] ;
#endif

and in both .c files I included it by:

在这两个。c文件中,我包括:

in the first file processed:

在第一个文件中处理:

#define MATSIZE 4
#include "def.h"

in the second .c file:

在第二个。c文件中:

extern int MATSIZE;
#include "def.h"

But I get

但我得到

error: variably modified ‘mat’ at file scope

What did I do wrong?

我做错了什么?

3 个解决方案

#1


2  

The concept of Variable Length Arrays (VLAs) is "new" to C99.

可变长度数组(VLAs)的概念是C99的“新”概念。

Before C99 you could only use real constants for specifying sizes of arrays. The following code was illegal either in block scope or file scope.

在C99之前,您只能使用真正的常量来指定数组的大小。以下代码在块范围或文件范围内是非法的。

const int size = 42; /* size is not a real constant */
int boo[size];

C99 introduced VLA for block scope. The example code above is legal C99, provided it happens in block scope. Your definition is at file scope and therefore invalid.

C99引入了VLA用于块范围。上面的示例代码是合法的C99,只要它在块范围内发生。您的定义在文件范围内,因此无效。


Also it is a really bad bad idea to have the same typedef refer to two different types.

同样的typedef引用两个不同的类型也是一个非常糟糕的坏主意。

#2


2  

When arrays are defined outside a block (at file scope or global scope), the size must be known at compile time. That means that the each dimension on the array must be a constant integral value (or, for the first dimension, it could be implied by the initializer for the array).

当数组在块外部定义(在文件范围或全局范围内)时,在编译时必须知道大小。这意味着数组中的每个维度必须是一个常量整数值(或者,对于第一个维度,它可以由数组的初始化器所暗示)。

If you used a C89 compiler, you might get a message about non-constant array dimensions. GCC 4.6.1 gives the 'variably modified mat at file scope' message.

如果您使用的是C89编译器,您可能会得到一个关于非常量数组维的消息。GCC 4.6.1给出了“文件范围内的可变修改的mat”消息。

C99 added Variable Length Arrays to the repertoire, but they can only appear inside a block or an argument list, where the size can be determined at runtime.

C99将可变长度数组添加到曲目中,但它们只能出现在一个块或参数列表中,其中大小可以在运行时确定。

So, in a function, you could legitimately write:

因此,在函数中,你可以合法地写:

extern int MATSIZE;

extern void func(void);

void func(void)
{
    typedef double mat[MATSIZE][MATSIZE];
    // ...
}

(The function declaration is needed to avoid the warnings like:

(需要使用函数声明来避免以下警告:

warning: no previous prototype for ‘func’ [-Wmissing-prototypes]

since I habitually compile with -Wmissing-prototypes.)

因为我习惯用- wmisast -原型编译。

The other issue is that in one file, MATSIZE is a compile-time (#defined) constant; in the other, there is apparently an integer variable MATSIZE. These are completely unrelated. The types therefore are different.

另一个问题是,在一个文件中,MATSIZE是一个编译时(#define)常量;另一方面,显然有一个整型变量。这些是完全无关的。因此,类型是不同的。


typdef is block scoped

wildplasser is concerned about whether typedef is block-scoped or global. It is block-scoped, as this otherwise execrable code demonstrates:

wildplasser关心的是typedef是块范围还是全局的。它是块作用域的,因为其他的execrable代码演示了:

#include <stdio.h>

static void function(void)
{
    typedef int i;
    i j = 1;
    printf("j = %d\n", j);
    {
    typedef double i;
    i j = 2.1;
    printf("j = %f\n", j);
    }
    {
    typedef char i[12];
    i j = "this works";
    printf("j = %s\n", j);
    }
}

int main(void)
{
    function();
    return(0);
}

If that was present to me for code review, it would be summarily rejected. However, it amply demonstrates a point.

如果这是对我的代码审查,它将被立即拒绝。然而,它充分证明了一点。

#3


1  

MATSIZE is not known. Which is why you are getting this issue.

MATSIZE尚不清楚。这就是为什么你会得到这个问题。

#ifndef DEF_H
#define DEF_H

#define MATSIZE 100 /* or whatever */

typedef double mat[MATSIZE][MATSIZE]

#endif 

#1


2  

The concept of Variable Length Arrays (VLAs) is "new" to C99.

可变长度数组(VLAs)的概念是C99的“新”概念。

Before C99 you could only use real constants for specifying sizes of arrays. The following code was illegal either in block scope or file scope.

在C99之前,您只能使用真正的常量来指定数组的大小。以下代码在块范围或文件范围内是非法的。

const int size = 42; /* size is not a real constant */
int boo[size];

C99 introduced VLA for block scope. The example code above is legal C99, provided it happens in block scope. Your definition is at file scope and therefore invalid.

C99引入了VLA用于块范围。上面的示例代码是合法的C99,只要它在块范围内发生。您的定义在文件范围内,因此无效。


Also it is a really bad bad idea to have the same typedef refer to two different types.

同样的typedef引用两个不同的类型也是一个非常糟糕的坏主意。

#2


2  

When arrays are defined outside a block (at file scope or global scope), the size must be known at compile time. That means that the each dimension on the array must be a constant integral value (or, for the first dimension, it could be implied by the initializer for the array).

当数组在块外部定义(在文件范围或全局范围内)时,在编译时必须知道大小。这意味着数组中的每个维度必须是一个常量整数值(或者,对于第一个维度,它可以由数组的初始化器所暗示)。

If you used a C89 compiler, you might get a message about non-constant array dimensions. GCC 4.6.1 gives the 'variably modified mat at file scope' message.

如果您使用的是C89编译器,您可能会得到一个关于非常量数组维的消息。GCC 4.6.1给出了“文件范围内的可变修改的mat”消息。

C99 added Variable Length Arrays to the repertoire, but they can only appear inside a block or an argument list, where the size can be determined at runtime.

C99将可变长度数组添加到曲目中,但它们只能出现在一个块或参数列表中,其中大小可以在运行时确定。

So, in a function, you could legitimately write:

因此,在函数中,你可以合法地写:

extern int MATSIZE;

extern void func(void);

void func(void)
{
    typedef double mat[MATSIZE][MATSIZE];
    // ...
}

(The function declaration is needed to avoid the warnings like:

(需要使用函数声明来避免以下警告:

warning: no previous prototype for ‘func’ [-Wmissing-prototypes]

since I habitually compile with -Wmissing-prototypes.)

因为我习惯用- wmisast -原型编译。

The other issue is that in one file, MATSIZE is a compile-time (#defined) constant; in the other, there is apparently an integer variable MATSIZE. These are completely unrelated. The types therefore are different.

另一个问题是,在一个文件中,MATSIZE是一个编译时(#define)常量;另一方面,显然有一个整型变量。这些是完全无关的。因此,类型是不同的。


typdef is block scoped

wildplasser is concerned about whether typedef is block-scoped or global. It is block-scoped, as this otherwise execrable code demonstrates:

wildplasser关心的是typedef是块范围还是全局的。它是块作用域的,因为其他的execrable代码演示了:

#include <stdio.h>

static void function(void)
{
    typedef int i;
    i j = 1;
    printf("j = %d\n", j);
    {
    typedef double i;
    i j = 2.1;
    printf("j = %f\n", j);
    }
    {
    typedef char i[12];
    i j = "this works";
    printf("j = %s\n", j);
    }
}

int main(void)
{
    function();
    return(0);
}

If that was present to me for code review, it would be summarily rejected. However, it amply demonstrates a point.

如果这是对我的代码审查,它将被立即拒绝。然而,它充分证明了一点。

#3


1  

MATSIZE is not known. Which is why you are getting this issue.

MATSIZE尚不清楚。这就是为什么你会得到这个问题。

#ifndef DEF_H
#define DEF_H

#define MATSIZE 100 /* or whatever */

typedef double mat[MATSIZE][MATSIZE]

#endif