以下代码在gcc 4.8和Clang 3.2下编译:
int main()
{
int size = 10;
int arr[size];
}
8.3.4 / 1的C ++标准说,数组的大小必须是一个整数常量表达式,size
似乎不是。这是两个编译器中的错误,还是我错过了什么?
最新的VC ++ CTP用这个有趣的消息拒绝代码:
error C2466: cannot allocate an array of constant size 0
有趣的是,它似乎认为size
为零。但至少它拒绝了代码。 gcc和Clang不应该这样做吗?
答案 0 :(得分:33)
这是variable length arrays或 VLA ,这是 C99 功能,但gcc和clang支持它作为< em> C ++ 而Visual Studio does not。所以Visual Studio
在这种情况下遵守标准并且在技术上是正确的。并不是说扩展程序很糟糕,Linux kernel depends on many gcc extensions,所以它们在某些情况下很有用。
如果您添加-pedantic
标记,gcc
和clang
都会向您发出警告,例如gcc
说( see it live ):
warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[size];
^
使用-pedantic-errors
标志会使此错误。您可以在这些文档Language Standards Supported by GCC和clangs Language Compatibility section中详细了解有关扩展程序的信息。
更新
draft C++ standard涵盖了5.19
常量表达式段落 3 中的整数常量表达式,并说:
整数常量表达式是整数或未整数枚举类型的表达式,隐式转换为prvalue,其中转换后的表达式是核心常量表达式。 [...]
从阅读中了解所有可能性并不是直观明显的,但Boost's Coding Guidelines for Integral Constant Expressions做得很好。
在这种情况下,因为使用 const 使用 literal 初始化size
就足以使其成为整数常量表达式 (参见[expr.const]p2.9.1)并将代码恢复为标准 C ++ :
const int size = 10;
使用 constexpr 也可以使用:
constexpr int size = 10;
阅读Difference between constexpr
and const
可能会有所帮助。
作为参考,C99 draft standard中8.3.4
段 1 的等效部分为6.7.5.2
数组声明符段 4 表示(强调我的):
如果大小不存在,则数组类型为不完整类型。如果大小是*而不是表达式,则数组类型是未指定大小的可变长度数组类型,只能在具有函数原型范围的声明中使用; 124)此类数组仍然是完整的类型。如果size是一个整型常量表达式,并且元素类型具有已知的常量大小,则数组类型不是可变长度数组类型; 否则,数组类型是可变长度数组类型。