“int size = 10;”产生一个常量expression式吗?

下面的代码在gcc 4.8和Clang 3.2下编译:

int main() { int size = 10; int arr[size]; } 

C ++标准的8.3.4 / 1指出数组的大小必须是一个整数常量expression式,这个size似乎不是。 这是两个编译器的错误,还是我错过了什么?

最新的VC ++ CTP用这个有趣的消息拒绝代码:

 error C2466: cannot allocate an array of constant size 0 

有趣的部分是它似乎认为size为零。 但至less它拒绝了代码。 gcc和Clang不应该这样做吗?

这是可变长度的数组或VLA ,它是C99特性,但是gcc和clang支持它作为C ++的扩展,而Visual Studio 则不支持 。 所以Visual Studio在这种情况下是遵循标准的,技术上是正确的。 不是说扩展是坏的, Linux内核依赖于许多gcc扩展 ,所以它们在某些情况下可能是有用的。

如果添加-pedantic标志, gccclang都会提醒你,例如gcc说( 看它现场 ):

 warning: ISO C++ forbids variable length array 'arr' [-Wvla] int arr[size]; ^ 

使用-pedantic-errors标志将会使这个错误。 您可以在这些文档中阅读更多关于扩展的信息。 语言标准支持GCC和clang语言兼容性部分 。

更新

C ++标准草案涵盖了第5.19常量expression式3段中的一个常数expression式 ,并说:

一个整型常量expression式是一个整型或非型枚举types的expression式,隐式转换为一个prvalue,其中转换后的expression式是一个核心常量expression式。 […]

通过阅读这一点,所有的可能性都不是很明显,但Boost的Integral Constantexpression式的编码指南在这方面做了很多工作。

在这种情况下,因为你正在初始化一个字面 size使用const就足以使其成为一个整型常量expression式 ,并将代码恢复为标准的C ++

 const int size = 10; 

使用constexpr也会起作用:

 constexpr int size = 10; 

这可能有助于读取constexprconst之间的区别 。

作为参考, C99标准草案中的8.3.4段落的等同部分将是6.7.5.2段落声明者的段落4强调我的 ):

如果大小不存在,则数组types是不完整的types。 如果size的大小是*,而不是一个expression式,则数组types是一个非指定大小的可变长度的数组types,它只能在具有函数原型作用域的声明中使用; 124)这样的数组是完整的types。 如果大小是一个整型常量expression式,并且元素types具有已知的常量大小,则数组types不是可变长度数组types; 否则,数组types是一个可变长度的数组types