[英]C typedef in header file variably modified at file scope
我需要在两个源文件中包括一些typedef定义:
typedef double mat[MATSIZE][MATSIZE] ;
所以我创建了def.h,其中包括:
#ifndef DEF_H
#define DEF_H
typedef double mat[MATSIZE][MATSIZE] ;
#endif
在两个.c文件中,我通过以下方式将其包括在内:
在处理的第一个文件中:
#define MATSIZE 4
#include "def.h"
在第二个.c文件中:
extern int MATSIZE;
#include "def.h"
但是我明白了
error: variably modified ‘mat’ at file scope
我做错了什么?
可变长度数组(VLA)的概念对于C99是“新的”。
在C99之前,您只能使用实常数来指定数组的大小。 以下代码在块范围或文件范围内都是非法的。
const int size = 42; /* size is not a real constant */
int boo[size];
C99引入了VLA 用于块范围 。 上面的示例代码是合法的C99,只要它发生在块范围内即可。 您的定义在文件范围内,因此无效。
同样的typedef引用两个不同的类型也是一个非常糟糕的主意。
当在块外部(在文件范围或全局范围)定义数组时,必须在编译时知道大小。 这意味着数组上的每个维数必须是一个恒定的整数值(或者,对于第一个维数,数组的初始化程序可能会暗示它)。
如果使用C89编译器,则可能会收到有关非恒定数组尺寸的消息。 GCC 4.6.1给出了“文件范围内的可变修改mat
”消息。
C99在库中添加了“可变长度数组”,但它们只能出现在块或参数列表中,在此可以在运行时确定大小。
因此,在一个函数中,您可以合法地编写:
extern int MATSIZE;
extern void func(void);
void func(void)
{
typedef double mat[MATSIZE][MATSIZE];
// ...
}
(需要使用函数声明来避免出现以下警告:
warning: no previous prototype for ‘func’ [-Wmissing-prototypes]
因为我习惯使用-Wmissing-prototypes
编译。)
另一个问题是,在一个文件中, MATSIZE
是一个编译时( #define
d)常量; 另一方面,显然有一个整数变量MATSIZE
。 这些是完全无关的。 因此,类型是不同的。
wildplasser关心typedef
是块作用域还是全局作用域。 它是块作用域的,如下面的可执行代码所示:
#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);
}
如果提供给我进行代码审查,则该摘要将被拒绝。 但是,它充分说明了这一点。
MATSIZE未知。 这就是为什么您遇到此问题。
#ifndef DEF_H
#define DEF_H
#define MATSIZE 100 /* or whatever */
typedef double mat[MATSIZE][MATSIZE]
#endif
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.