克++:数组边界不是一个整数常量(g++: array bound is not an intege

2019-09-18 20:14发布

随着代码,

const double rotationStep = 0.001;
const int N = 2*int(M_PI/rotationStep) + 3;

static unsigned int counts[N];

g++给出了错误:

阵列边界不是一个整数之前»]«令牌恒定

我使用的g++ / gcc 4.6.1

谁能告诉我,为什么g++抱怨的表达?

Answer 1:

作为ISO C ++标准2003的,这不是一个积分常数表达式 。 引用标准的第5.19:

一个积分常数表达式可以只涉及文字(2.13),统计员, const变量或常量表达式(8.5),积分或枚举类型的非类型TEM-板参数初始化积分或枚举类型的静态数据成员,和sizeof表达式。 如果他们被强制转换为整型或枚举类型的浮动文字(2.13.3)只能出现。

你可以改变这一点:

const double rotationStep = 0.001;
const int N = 2*int(M_PI/rotationStep) + 3;

为此:

const int inverseRotationStep = 1000;
const int N = 2*int(M_PI)*inverseRotationStep + 3;

(这是假设M_PI的某处定义的;它不是标准中所规定,但它是一个常见的扩展)。

2011年的ISO C ++标准放松了这一点。 5.19p3(引用了N3337草案)说:

整数表达式中是一体的或无作用域枚举类型的字面常量表达式。

认为 2*int(M_PI/rotationStep) + 3 ,因此N ,根据新的规则,有资格,但很可能你的编译器还没有实现它们。



Answer 2:

问题是...

g++ gives: array bound is not an integer constant before »]« token

一个const的值不是一个常量表达式(虽然它很容易理解为什么这会迷惑你)。

编辑:我认为C使用时我第一次看到这一点。 这里的问题是,这种表达不被在编译时评价:

const int N = 2*int(M_PI/rotationStep) + 3;

虽然这将是

const int N = 10;

作为@ildjarn在评论中指出,浮点运算,不能保证在编译时进行评估。 下面是相关的SO后,我发现。



Answer 3:

爱德已经指出,浮点运算,包括常量折叠的优化,并不能保证在编译时发生。 英特尔的页面上的主题给出了几个例子,但主要是它是舍入行为可能是不同的,浮点运算可能会抛出异常。 本文去深入多一点(第8.3节,“算术还原”)。

GCC只做支持

“浮点表达式收缩如稠合形成乘加运算如果目标具有用于他们的本地支持”

如在用于FFP-合同标志描述中所提到的编译器优化手册。



文章来源: g++: array bound is not an integer constant