【问题标题】:How to declare a static variable but not define it如何声明一个静态变量但不定义它
【发布时间】:2009-12-08 04:35:09
【问题描述】:

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

例子:

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

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

【问题讨论】:

  • static 表示它在编译时加载。为什么你不想初始化它?
  • Woot4Moo:在 C 中将全局变量设为“静态”意味着它在当前“编译单元”(通常是 .c 文件及其所有头文件)之外不可见。所有不是“extern”的全局变量都在编译时分配空间。

标签: c++ c static definition


【解决方案1】:

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

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

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

编辑:

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

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

【讨论】:

  • "someName" 也被使用了,我的帖子稍微改了一下,谢谢。
【解决方案2】:
static some_type some_name; /*definition */

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

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

【讨论】:

  • 我认为您没有正确使用“IMO”。这听起来不像是一种意见。
  • Prasoon的意见;它也符合标准,所以他的意见是正确的(根据标准)。
【解决方案3】:

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

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

【讨论】:

  • 谢谢。这正是我所需要的。仅供参考,我不得不查找暂定定义。这篇文章最终为我提供了我需要的所有信息:stackoverflow.com/a/3095957/937363
【解决方案4】:

一点背景:

正如其他人指出的那样,静态变量具有内部链接,这意味着它们只能在同一个“编译单元”或源文件中使用。这意味着您不能在头文件中声明它,在一个编译单元中为其赋值,并期望该值出现在另一个编译单元中。

当您初始化一个全局变量(静态或非静态)时,编译器只需将初始值放入为变量分配的内存位置的可执行文件中。换句话说,它总是有一个初始值。当然,您以后可以随时使用赋值语句覆盖该值。

建议:

如果你真的不知道编译时变量的值,那么你应该在你的初始化函数中动态分配它。

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 文件)中使用同一个全局变量,也不能在头文件中使用。

【讨论】:

    【解决方案5】:

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

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

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

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

    【讨论】:

      【解决方案6】:

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

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

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

      static SomeType SomeVar_;

      在你的文件中,放

      extern SomeType SomeVar_

      然后将初始化放在任何你想要的地方。

      【讨论】:

      • 这将导致链接器错误,因为static 定义具有内部链接,并且使用extern 声明它的文件无法访问。
      猜你喜欢
      • 1970-01-01
      • 2019-02-13
      • 2016-05-27
      • 1970-01-01
      • 1970-01-01
      • 2012-11-03
      • 2023-03-06
      • 2010-11-03
      • 2014-07-24
      相关资源
      最近更新 更多