如何声明静态变量但不定义它

时间:2009-12-08 04:35:09

标签: c++ c static definition

有时我们需要预先声明一个静态变量然后使用它。 但是这个声明的变量名可能是错误的,并且编译器无法检测到它,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”不同,我们在开头使用了错误的变量。 如果预声明语句没有定义任何内容,编译器将检测到错误。

那么,如何声明静态变量但不定义它?如何将预声明更改为新的声明,使编译器可以检测到错误的名称?

6 个答案:

答案 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_

而不是将初始化放在任何地方。