[英]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.