【问题标题】:'Initializer not constant' on global variable?全局变量上的“初始化程序不是常量”?
【发布时间】:2014-04-13 08:56:34
【问题描述】:

所以我在编译以下代码时收到“初始化元素不是常量”错误:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

float wl = 2.0f;
float k = 2.0f * (float) M_PI / wl;

int main ()
{
     //Do stuff
}

如果我将 "float k" 移动到 main 方法中,则不会出现错误,但这对我来说不是一个选项,因为我需要 float k 作为全局变量。即使我把它改成这样:

const float wl = 2.0f;
const float k = 2.0f * (float) M_PI / wl;

错误仍然发生。我该如何解决这个问题?

【问题讨论】:

  • 考虑在一开始就在main 中为k 赋值,同时将其声明为没有初始化的全局变量。

标签: c global-variables


【解决方案1】:

根据 C99 标准:

§6.7.8 初始化

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

在这里使用const 没有帮助,因为在C 中,const 变量并不是真正的常量。查看this post了解更多详情。


要解决这个问题,您可以使用 预处理器 使 wl 保持不变:

#define wl 2.0f

通过这样做,2.0f * (float) M_PI / wl 可以成为编译时间常数。

【讨论】:

    【解决方案2】:

    Globalstatic 变量在初始化时存储在数据段 (DS) 中,而在未初始化时由符号 (BSS) 开始块。这些变量有一个固定的内存位置,内存是在编译时分配的。
    C 不允许使用非常量值初始化全局值。

    C99 Standard: Section 6.7.8:
    
    All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
    

    您需要将main 中的初始化移动到保持声明为全局

    float wl = 2.0f;
    float k  ;
    
    int main ()
    {
          k = 2.0f * (float) M_PI / wl;
         //Do stuff
    }
    

    【讨论】:

      【解决方案3】:

      在我之上@GoldRanger 准确地引用了标准,从而解释了您遇到的问题。从技术上讲,因为您在 k 的初始化中有一个变量,所以它被认为是 non-constant

      为了添加一些上下文,我将把它放在这里:

      当程序编译时,它将全局变量放在它们自己的二进制部分中(我不太熟悉 linux 或 windows 可执行格式,但在 mac 上它们被放在 __DATA 段中)。因此,当您输入该行 float k = 2.0f * (float) M_PI / wl; 时,编译器不够聪明* 无法识别 wl 实际上是编译时的常量,并且您希望使用 wl 的初始值初始化 k

      *smart 在这里的描述并不完全正确。一般来说,由于wl 没有被声明为 const,所以表达式通常不完全是一个常量表达式,所以编译器对此一无所知。我想这可能是一个语义问题,或者可能只是我在与自己争论我使用的措辞。

      为了做你想做的事,我通常使用#define 作为我的初始常量,它将在整个程序中使用:

      #define kwlconst 2.0f
      float wl = kwlconst;
      float k = 2.0f * (float) M_PI / kwlconst;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多