全局变量上的’初始值不是常数’?

因此,在编译以下代码时,我得到’initializer element not constant’错误:

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

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

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

错误仍然发生。 我该如何解决?

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 } 

根据C99标准:

§6.7.8初始化

  1. 具有静态存储持续时间的对象的初始值设定项中的所有表达式应为常量表达式或字符串文字

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


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

 #define wl 2.0f 

通过这样做, 2.0f * (float) M_PI / wl可以是编译时常量。

在我之上@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;