所以我要做的是在file2.c中使用file1.c中的变量。
我已经在这里看到了一些答案,但我仍然得到了和以前一样的错误。 (error: variably modified at file scope
)
我在file1.c上的内容是这样的:
extern int num = 0;
struct abc *do_something(int n){
num = n;
}
/*more code below*/
现在我想在file2.c上使用num
。我有这个:
#include <something.h> /*which has file1.h inside*/
int num;
struct list_t list[num]; /*error here*/
/*code that uses the initialized list below*/
我尝试使用像#define test_num num
这样的东西,但它也没用。我需要列表在file2上是“全局”的,所以我可以用不同的方法。
答案 0 :(得分:1)
实际上你有两个问题。第一个与您的错误相关的是,当编译器看到数组num
的声明时,list
的值为 unknown 。编译器不知道任何其他translation unit(包含所有包含头文件的源文件)的任何内容,它只知道它正在处理的翻译单元。
第二个问题更具理论性,并且在编译时数组的大小是固定的,并且在运行时更改变量num
不会改变大小阵列。
第一个问题可以通过将num
的初始化移动到实际使用它的translation unit来解决。哦,并没有将其初始化为零,零大小的数组没有多大用处。
使用malloc
和realloc
使用指针和动态分配可以解决第二个问题。
答案 1 :(得分:1)
list
声明中的错误与全局num
的定义无关,尽管这也是错误的,而是您尝试使用外部变量对数组进行维度一个功能。这是非法的,也是胡说八道。实例化num
时list
的值是非确定性的,即使num
首先被初始化,您也要声明一个零长度的数组。
您将extern
放在错误的位置。在file1.c中你应该有:
int num = 0 ;
在file2.c中:
extern int num ;
通常你会将extern
声明放在头文件中 - 这允许编译器检查声明和定义之间的类型匹配,并允许在单个点的多个文件中使用正确和一致的声明例如,您应该更改类型的维护。
// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE
extern int num ; // Declaration
#endif
// file1.c
#include "file1.h"
int num = 0 ; // Definition/Instantiation
// file2.c
#include "file1.h"
int f()
{
return num ; // Use file1::num
}
所有说真的根本不使用全局变量。这是不好的做法和不必要的。更确切地说:
// file1.h
#if !defined file1_INCLUDE
#define file1_INCLUDE
void setNum( int n ) ;
int getNum() ;
#endif
// file1.c
#include "file1.h"
static int num = 0 ; // Protected by file scope
void setNum( int n ) { num = n ; }
int getNum() { return n ; }
// file2.c
#include "file1.h"
int f()
{
setNum( getNum() + 1 ) ; // Increment num (example r/w access)
return getNum() ;
}
这有许多优点,包括:
进一步阅读A Pox on Globals(与嵌入式系统有关,但一般情况下也同样适用。
答案 2 :(得分:0)
要在两个文件之间共享一个全局变量,您应该知道该变量属于源文件,该文件声明没有&#34; extern&#34;。因此,它也应该在该源文件中初始化。使用extern告诉编译器,它会在链接时从其他一些目标文件中找到该变量。
正如Joachim所写,使用此全局变量时,您的数组也存在问题。