头文件中的C typedef在文件范围内进行了可变修改
我需要在两个源文件中包含一些typedef定义:头文件中的C typedef在文件范围内进行了可变修改,c,header,typedef,C,Header,Typedef,我需要在两个源文件中包含一些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
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
我做错了什么?不知道MATSIZE。这就是为什么你会遇到这个问题
#ifndef DEF_H
#define DEF_H
#define MATSIZE 100 /* or whatever */
typedef double mat[MATSIZE][MATSIZE]
#endif
MATSIZE不得而知。这就是为什么你会遇到这个问题
#ifndef DEF_H
#define DEF_H
#define MATSIZE 100 /* or whatever */
typedef double mat[MATSIZE][MATSIZE]
#endif
可变长度阵列(VLA)的概念对C99来说是“新的” 在C99之前,您只能使用实常量来指定数组的大小。以下代码在块范围或文件范围内都是非法的
const int size = 42; /* size is not a real constant */
int boo[size];
C99为块范围引入了VLA。上面的示例代码是合法的C99,前提是它发生在块范围内。您的定义在文件范围内,因此无效
另外,让同一类型的def表示两种不同的类型是一个非常糟糕的想法。可变长度数组(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
at file scope”消息
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原型编译
另一个问题是,在一个文件中,MATSIZE
是一个编译时(#define
d)常量;在另一个变量中,显然有一个整数变量MATSIZE
。这些完全无关。因此,类型不同
typdef是块范围的
关注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);
}
#包括
静态空隙函数(void)
{
类型定义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=“这是有效的”;
printf(“j=%s\n”,j);
}
}
内部主(空)
{
函数();
返回(0);
}
如果提交给我进行代码审查,它将被立即拒绝。但是,它充分说明了一点。当数组在块外部(在文件范围或全局范围)定义时,必须在编译时知道大小。这意味着数组上的每个维度必须是一个常量整数值(或者,对于第一个维度,它可以由数组的初始值设定项暗示)
如果使用C89编译器,可能会收到一条关于非常量数组维度的消息。GCC 4.6.1给出了“文件范围内的可变修改mat
at file scope”消息
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原型编译
另一个问题是,在一个文件中,MATSIZE
是一个编译时(#define
d)常量;在另一个变量中,显然有一个整数变量MATSIZE
。这些完全无关。因此,类型不同
typdef是块范围的
关注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);
}
#包括
静态空隙函数(void)
{
类型定义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=“这是有效的”;
printf(“j=%s\n”,j);
}
}
内部主(空)
{
函数();
返回(0);
}
如果提交给我进行代码审查,它将被立即拒绝。但是,它充分说明了一点。您还必须定义MATSIZE
。请看,我有“#define MATSIZE 4#define MATLENGTH MATSIZE*MATSIZE”#在其中一个先处理的.c文件中包含“def.h”和“extern int MATSIZE#在secondOne.c文件中包含“def.h”表示MATSIZE是一个常量。另一个说这是一个(外部)int。其中一个在撒谎……不。在文件1中,它是一个预处理器定义。每次出现字符串“4”时,它都会指示预处理器将字符串“MATSIZE”替换为字符串“4”。(因此编译器在扫描.h文件时将有效地看到typedef double mat[4][4];
)。第二个.c文件声明了一个名为MATSIZE(但值未知)的(外部)int,因此编译器将有效地看到typedef double-mat[MATSIZE][MATZIZE]代码>扫描.h文件时,认为MATSIZE是一个具有未知值的(外部)int;这是不可接受的。是的,或多或少。您想要的是,保证“mat”的typedef每次被anot包含时都会生成完全相同的类型