因此,在编译以下代码时,我得到了"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"
,没有错误,但这对我来说不是一个选项,因为我需要float k作为全局变量。即使我把它改成这个:
const float wl = 2.0f;
const float k = 2.0f * (float) M_PI / wl;
错误仍然会发生。我该如何解决这个问题?
根据C99标准:
§6.7.8初始化
- 具有静态存储持续时间的对象的初始值设定项中的所有表达式都应为常量表达式或字符串文字
使用const
在这里没有帮助,因为在C中,const
变量并不是真正的常量。查看此帖子了解更多详细信息。
要计算,可以使用预处理器使wl
恒定:
#define wl 2.0f
通过这样做,2.0f * (float) M_PI / wl
可以是一个编译时间常数。
Global
和static
变量在初始化时存储在数据段(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
}
Above me@GoldRanger准确地引用了该标准,从而解释了您遇到的问题。从技术上讲,由于k
的初始化中有一个变量,因此它被认为是non-constant
。
为了添加一些上下文,我将把它放在这里:
当程序编译时,它会将全局变量放在二进制文件的自己部分(我不太熟悉linux或windows可执行文件格式,但在mac上,它们被放在__DATA段中)。因此,当你放那行float k = 2.0f * (float) M_PI / wl;
时,编译器不够聪明*,无法识别wl
在编译时实际上是一个常数,并且你希望k
用wl
的初始值初始化。
*这里对smart的描述并不完全正确。一般来说,由于wl
没有声明为const,因此表达式通常不是一个常量表达式,因此编译器对此一无所知。我想这可能是一个语义问题,也可能只是我在与自己争论我使用的措辞。
为了做你想做的事情,我通常使用#define
作为我的初始常数,它将在整个程序中使用:
#define kwlconst 2.0f
float wl = kwlconst;
float k = 2.0f * (float) M_PI / kwlconst;