"int size = 10;" 产生一个恒定的表达?

Kno*_*abe 13 c++ arrays compile-time-constant variable-length-array c++11

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

int main()
{
  int size = 10;
  int arr[size];
}
Run Code Online (Sandbox Code Playgroud)

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

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

error C2466: cannot allocate an array of constant size 0
Run Code Online (Sandbox Code Playgroud)

有趣的是,它似乎认为size是零.但至少它拒绝了代码.gcc和Clang应该不一样吗?

Sha*_*our 33

这是可变长度数组VLA,它是C99功能,但gccclang支持它作为C++中的扩展,而Visual Studio 则不支持.因此Visual Studio在这种情况下遵守标准并且在技术上是正确的.并不是说扩展是坏的,Linux内核依赖于许多gcc扩展,因此它们在某些上下文中很有用.

如果你同时添加-pedantic标志gcc并且clang会警告你这个,例如gcc说(看到它):

warning: ISO C++ forbids variable length array 'arr' [-Wvla]
  int arr[size];
              ^
Run Code Online (Sandbox Code Playgroud)

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

更新

草案C++标准涵盖的是一个整型常量表达式在部分5.19 常量表达式3,并说:

整数常量表达式是整数或未整数枚举类型的表达式,隐式转换为prvalue,其中转换后的表达式是核心常量表达式.[...]

从阅读这一点看,所有可能性都不是直观明显的,但Boost的积分常数表达式编码指南做得很好.

在这种情况下,因为要初始化size文字使用常量就足以使之成为一体的常量表达式(见[expr.const] P2.9.1),并且还使代码重新成为标准C++:

const int size = 10;
Run Code Online (Sandbox Code Playgroud)

使用constexpr也会起作用:

constexpr int size = 10;
Run Code Online (Sandbox Code Playgroud)

它可能有助于阅读之间的区别constexprconst.

为了参考的等效部分到8.3.41C99标准草案将部分6.7.5.2 组声明4,其表示(重点矿山):

如果大小不存在,则数组类型是不完整类型.如果大小是*而不是表达式,则数组类型是未指定大小的可变长度数组类型,只能在具有函数原型范围的声明中使用; 124)这样的阵列仍然是完整的类型.如果size是一个整型常量表达式,并且元素类型具有已知的常量大小,则数组类型不是可变长度数组类型; 否则,数组类型是可变长度数组类型.