【问题标题】:Why can't I initialize a static variable with a non literal value?为什么我不能用非文字值初始化静态变量?
【发布时间】:2012-03-26 17:46:58
【问题描述】:

我有这个代码:

int foo(void){
    return 1;
}

int main(void){
    static const int x = foo();

    //do stuff
    return 0;
}

但是我收到一个关于使用非常量值初始化静态变量的错误。我认为它与 const 说明符有关,但事实并非如此。我结束了删除 const 关键字并执行此操作:

int foo(void){
    return 1;
}

int main(void){
    static int x = 0;
    if (x == 0) x = foo();

    //do stuff
    return 0;
}

现在,为什么编译器不能延迟 static int x 变量的初始化直到它被使用,更重要的是,为什么它不能把它放在一个读写部分,并强制它不是在编译时写入?我想在我的代码中使用const AND static 关键字来改进语义,但我并不关心编译器如何处理这个问题,只要让它工作就行了。

我对 C 标准的理解是错误的吗?还是我的编译器很烂?它是 MSVC 9.0。

【问题讨论】:

  • main 中的静态变量有什么用?
  • 'x' 在您的示例上下文中看起来像一个局部变量。为什么你希望它是静态的?
  • @ValAkkapeddi:通常是因为您不需要/不想为每次调用该函数重新初始化它。
  • 对不起,它实际上不在 main 中,我只是将它放在 main 中,以便可以独立编译 sn-p。
  • @tchap:如果对象太大而无法放入堆栈,或者您想重新输入main,这很有用。 (在 C 中,递归调用 main 是合法的。)

标签: c static constants


【解决方案1】:

C 需要它。

来自 C 标准:

(C99, 6.7.8p4) "具有静态存储持续时间的对象的初始化程序中的所有表达式都应为常量表达式或字符串文字。"

请注意,const 限定符并不意味着常量,而是只读的。 const 对象在 C 中不是常量。

静态对象不能被非常数值初始化的原因与静态对象的初始化完成“在程序启动之前”(C99,6.2.4p3) .

【讨论】:

  • 请解释一下 const 对象和 C 中的常量有什么区别。C 中的常量是字面值?
  • C 中常量表达式的定义极其有限。它在 C99 的 6.6 常量表达式中定义(html 版本在 port70.net/~nsz/c/c99/n1256.html#6.6
  • @Spidey 一个常量基本上是一个标量文字,定义见 C99, 6.4.4。常量是常量表达式。 const 对象既不是常量也不是常量表达式。
  • 那你为什么可以在 C++ 中这样做呢?
  • @SahandMozaffari C 和 C++ 是两种不同的语言(即使 C 启发了 C++,然后 C++ 启发了 C)。请注意,在 C++ 中,与 C 不同,const 实际上是一个常量。
【解决方案2】:

初始化值必须在编译或链接时确定。 C 没有可以在程序启动时运行的构造函数的概念。

【讨论】:

    【解决方案3】:

    此约束来自 C 标准的第 6.7.8/4 节,因此它不仅仅是您的编译器:

    具有静态存储持续时间的对象的初始化程序中的所有表达式都应为常量表达式或字符串字面量。

    这样做的原因是,与 C++ 标准不同,C s 不需要执行环境来提供预运行初始化的入口点(当然也不会禁止它;静态初始化的方式和时机(5.1.2) 是未指定)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-19
      • 2012-03-28
      • 1970-01-01
      • 2019-12-23
      • 2015-09-06
      • 1970-01-01
      相关资源
      最近更新 更多