'初始化程序不是常数'关于全局变量?

时间:2014-04-13 08:56:34

标签: c global-variables

编译以下代码时,我得到'initializer element not constant'错误:

#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
}

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

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

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

3 个答案:

答案 0 :(得分:6)

根据C99标准:

  

§6.7.8初始化

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

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


要计算,您可以使用预处理器使wl保持不变:

#define wl 2.0f

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

答案 1 :(得分: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
}

答案 2 :(得分:0)

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

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

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

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

为了做你正在尝试做的事情,我通常会使用#define kwlconst 2.0f float wl = kwlconst; float k = 2.0f * (float) M_PI / kwlconst; 作为整个程序中使用的初始常量:

{{1}}