C++ array size declaration and const

9

我刚开始学习C++,之前有C语言基础。

在C语言(89/90)中,const并不是一个真正的常量(与#defineenum或字面值相比),而是一旦设置为只读。也就是说,我可以:

const int x = rand();

这是可以接受的,因为关键点在于x直到运行时才知道。因此,我无法

int arr[x]; // error - x is not a compile-time constant

然后,C标准之一(99?)允许使用可变长度数组。虽然我通常遵循C的ANSI标准编码,但现在我正在学习C++11时,这实际上产生了影响。
据我所知,C++不允许使用可变长度数组。然而,许多编译器将其作为扩展功能(如GCC?)。问题是,现在我正在学习C++11,我无法确定我编写的代码是有效的C++,还是C++扩展了C99兼容性。例如:
std::default_random_engine e{};
std::uniform_int_distribution<int> d{};
const int x{d(e)};
int arr[x]; // compiles

我无法确定这是否为有效的C++代码。显然,x的值直到运行时才知道。我想我可能不理解C和C ++之间的const区别?


不合法。请使用标志“-std = ...”,其中“...”是标准,例如“c ++ 11”或“c ++ 98”。 - juanchopanza
2
你也可以使用 -pedantic - Jarod42
不适用于C++11,但C++14允许具有运行时大小的堆栈数组。 - Johannes Schaub - litb
1
@JohannesSchaub-litb,数组扩展 TS 没有被纳入 C++14。 - chris
@JohannesSchaub-litb,据我记得,它们曾经在其中,但被撤出了。我在N3797中根本看不到它们。有一个Rapperswil旅行报告,其中包含更多关于它的状态的信息。 - chris
显示剩余6条评论
1个回答

11

你是正确的,VLAs 是 C99 特性(C11 中为可选项),而 C++ 标准不包括此特性,尽管 gccclang 允许在 C++ 中使用它们作为扩展功能。我们可以看到它们被禁止了,通过查看草案 C++11 标准中的第 8.3.4 节 数组,其中写道:

D1 [ constant-expressionopt] attribute-specifier-seqopt
     ^^^^^^^^^^^^^^^^^^^^^^

对于gccclang,使用-pedantic标志将在您使用扩展时发出警告。 如果您的目标是C++11,则还应使用-std=c++11进行指定。 您可以使用-pedantic-errors将警告转换为错误。 如果您使用-pedantic编译代码,应该会看到以下警告:

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

gcc在其GCC支持的语言标准页面记录了他们对各种标准、默认设置和强制标准所需标志的支持情况,并且说明:

要获得标准所需的所有诊断信息,您还应指定 -pedantic(如果想要将它们作为错误而非警告,则为 -pedantic-errors)。

一般而言,clang支持gcc所支持的内容,但您可以通过语言兼容性页面了解更多详细信息。

请注意,正如GingerPlusPlus所提到的:std:vector被认为是C++中VLA的替代品。


太棒了!看起来这确实使用了C99扩展。 - zac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接