有时我们需要预先声明一个静态变量然后使用它。 但是这个声明的变量名可能是错误的,并且编译器无法检测到它,oops!
示例:
/* lots of codes */
static some_type some_name; /* pre-declaration */
/* but it may define "some_name" */
/* use some_name */
/* lots of codes */
static some_type someName = initialization; /* definition */
/* use someName */
/* lots of codes */
“some_name”和“someName”不同,我们在开头使用了错误的变量。 如果预声明语句没有定义任何内容,编译器将检测到错误。
那么,如何声明静态变量但不定义它?如何将预声明更改为新的声明,使编译器可以检测到错误的名称?
答案 0 :(得分:9)
gcc
会在您描述的情况下发出警告:
./x.c:3010: warning: 'someName' defined but not used
解决方案:执行您当前正在执行的操作,但不要忽略编译器警告;)
修改强>
使用您更新的问题:不,我不相信有一种方法可以简单地声明一个静态变量(也没有定义它)。
常见的解决方案只是确保所有全局范围变量只声明一次,如果需要则使用初始化器。
答案 1 :(得分:8)
static some_type some_name; /*definition */
静态变量some_name已初始化为0;这是定义,而不仅仅是声明。
IMO,静态变量不能仅使用extern说明符在C中声明,因为它的链接始终是内部的。
答案 2 :(得分:4)
无法在C语言中创建具有内部链接的对象的非定义声明(即术语中的“预声明”)。
尽可能接近暂定定义,这就是您的示例中的内容。但是如果出现错字,暂定定义将隐含地产生一个独立的定义,而不是链接器错误。
答案 3 :(得分:2)
一点背景:
正如其他人所指出的,静态变量具有内部链接,这意味着它们只能在相同的“编译单元”或源文件中使用。这意味着你不能在头文件中声明它,在一个编译单元中为它赋值,并期望该值出现在另一个编译单元中。
初始化全局变量(静态或非静态)时,编译器只需将初始值放入为变量分配的内存位置的可执行文件中。换句话说,它始终具有初始值。当然,您可以随后使用赋值语句覆盖该值。
建议:
如果您在编译时确实不知道变量的值,那么您应该在初始化函数中动态分配它。
static some_type some_variable; /* = 0 by default */
/* some code */
void MyInitializations()
{
some_variable = some_value;
}
如果你想在一个地方声明变量,比如一个头文件,并在源文件中定义它,那么你应该使用'extern'声明,它告诉编译器不要担心变量在哪里。链接器将找到变量的位置,就像它在另一个文件中找到一个函数并填写地址一样。
部首:
extern some_type some_variable;
源文件1:
void UseSomeVariable()
{
x = some_variable;
}
源文件2:
some_type some_variable = some_value;
/* possible also uses some_variable */
如果您只想在一个地方声明变量并在另一个地方定义变量,请不要使用'static'关键字。这样做的缺点是您不能在不同的编译单元(.c文件)中使用相同的全局变量,并且不能在头文件中使用它。
答案 4 :(得分:0)
您需要预先声明变量吗?如果没有,那么将初始化器放在唯一的声明上。如果初始化器不是常量(这需要C ++,而不是C,IIRC),那么我就能理解为什么需要在使用它之前预先声明它。但是,初始化程序所需的一切都可以在它之前预先声明。
因此,将常量defs和静态变量放在每个文件的顶部,这样静态的初始化程序就可以在常量之后。然后,您不需要单独的初始化行。
在任何其他情况下,caf的权利:为了获得警告的好处,使用gcc编译代码是值得的。我已经用g ++为C ++中的MFC GUI做了这个。 (编译,不运行!)
如果以后没有初始化程序的定义,AFAIK C无法编写将产生错误的弱定义。总是隐含0,因为变量进入BSS部分。
答案 5 :(得分:-1)
如果我理解你的问题,也许你只是没有正确对待它。
对于你的程序说extern SomeType someVar_;
你会不会更好,我知道这个变量会被人知道,但我不想告诉你它现在是什么。
因此,您可以在单独的文件中声明您的变量说
static SomeType SomeVar_;
在你的档案中,输入
extern SomeType SomeVar_
而不是将初始化放在任何地方。