8

例子

int main()
{
    const int i = 1.0; // Notice I am assigning a double to an int here
    char a[i];
}

问题

编译上面的代码g++ -O0 -Wall -pedantic -ansi -std=c++11没有错误(除了一个未使用的变量)。但是,如果我删除-std=c++11,我会收到以下警告:

警告:ISO C++ 禁止变长数组

根据这个 SO question,我相信在 C++03 中,代码是无效的。但是,有人能解释一下 C++11 中的规则是如何变化的吗?

(这个问题是我之前回答的问题的结果。)

4

1 回答 1

7

数组绑定必须是整数常量表达式,请参阅 8.3.4 [dcl.array]/1(C++03 和 C++11 中的措辞相同):

如果常量表达式 (5.19) 存在,它应该是一个整数常量表达式并且它的值应该大于零。

在 C++03 中,整数常量表达式不能由浮点文字初始化,除非强制转换为整数类型,参见 5.19 [expr.const]/1 的最后一句话:

一个整数常量表达式只能包含字面量 (2.13)、枚举数、const变量或整数或枚举类型的静态数据成员,这些成员使用常量表达式 (8.5)、整数或枚举类型的非类型模板参数和sizeof表达式进行初始化。浮动文字 (2.13.3) 只有在转换为整数或枚举类型时才能出现。

这意味着在 C++03i中不是整数常量表达式,因此不能用作数组绑定。

GCC 和 Clang 允许可变长度数组作为 C++03 的扩展,因此它使用非常量边界进行编译,但您会收到带有-pedantic. 更改常量的初始值设定项以将其强制转换为整数类型会i生成一个有效的整数常量表达式:

const int i = (int) 1.0;

随着这种变化,数组不再是可变长度,即使使用-pedantic.

在 C++11 5.19 [expr.const]/3 中说:

文字常量表达式是文字类型的纯右值核心常量表达式,但不是指针类型。整型常量表达式是整型或无范围枚举类型的字面常量表达式。

前面的(相当长的)段落描述了核心常量表达式的规则,但基本上在 C++11 中,双初始值设定项不会阻止i成为核心常量表达式,即使没有强制转换,所以它是一个整数常量表达式,因此是有效的数组绑定,所以没有警告。

于 2012-06-07T13:41:03.003 回答