7

有时我们需要预先声明一个静态变量然后使用它。但是这个声明的变量名可能是错误的,编译器检测不到,哎呀!

例子:

/* 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”不同,我们在开始时使用了错误的变量。如果预声明语句没有定义任何东西,编译器会检测到错误。

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

4

6 回答 6

9

gcc在您描述的情况下会发出警告:

./x.c:3010: warning: 'someName' defined but not used

解决方案:做你目前正在做的事情,但不要忽略编译器警告;)

编辑:

对于您更新的问题:不,我不相信有一种方法可以简单地声明一个静态变量(也不需要定义它)。

常见的解决方案是确保所有全局范围变量只声明一次,如果需要,则使用初始化程序。

于 2009-12-08T04:41:53.437 回答
8
static some_type some_name; /*definition */

静态变量 some_name 已初始化为 0;它是定义,而不仅仅是声明。

IMO,不能只在 C 中使用 extern 说明符声明静态变量,因为它的链接始终是内部的。

于 2009-12-08T04:41:46.107 回答
4

不可能在 C 语言中创建具有内部链接的对象的非定义声明(即您的术语中的“预声明”)。

尽可能接近的是一个暂定定义,这就是您在示例中所拥有的。但是如果出现拼写错误,暂定定义将隐含地产生一个独立的定义,而不是链接器错误。

于 2009-12-08T05:26:06.393 回答
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 文件)中使用相同的全局变量,也不能在头文件中使用它。

于 2009-12-08T04:59:39.330 回答
0

你需要预先声明变量吗?如果不是,则将初始化程序放在唯一的声明上。如果您的初始化程序不是常量(这需要 C++,而不是 C、IIRC),那么我可以理解为什么您需要在使用它的某些函数之前预先声明它。但是,初始化器所需的一切都可以在它之前预先声明。

所以把你的常量定义和静态变量放在每个文件的顶部,这样你的静态初始化器就可以紧跟在常量之后。然后你不需要单独的初始化行。

在任何其他情况下,caf 是对的:值得让您的代码使用 gcc 编译,只是为了从它的警告中受益。我已经为 C++ 中的 MFC GUI 为 g++ 完成了该操作。(编译,而不是运行!)

AFAIK C 没有办法编写弱定义,如果稍后没有带有初始化程序的定义,则会产生错误。总是有一个隐含的 0,因为变量位于 BSS 部分。

于 2009-12-08T04:49:47.963 回答
-1

如果我理解您的问题,也许您只是没有以正确的方式面对它。

对你的程序说,你会不会更好extern SomeType someVar_;,我知道这个变量是已知的,但我不想告诉你它现在是什么。

因此,您可以在一个单独的文件中声明您的变量说

static SomeType SomeVar_;

在你的文件中,把

extern SomeType SomeVar_

而不是把初始化放在任何你想要的地方。

于 2009-12-08T04:57:00.303 回答