在 C89 的数组声明中使用 sizeof()

Using sizeof() in array declarations in C89

我的印象是可变大小数组声明在 C89 中是不可能的。但是,当使用 clang -ansi 编译时,我能够 运行 以下代码:

double array[] = { 0.0, 1.0, 2.0, 3.0, 4.0 };
double other_array[sizeof(array)] = { 0.0 };

这是怎么回事?这不被认为是可变大小数组声明吗?

首先,让我们看看数组(不是)VLA 的条件。 C11 文档,章节 §6.7.6.2,

[...] If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; [...]

针对您的情况,sizeof 是一个编译时运算符,因此它生成一个被视为编译时常量表达式的值。其大小指定为编译时常量表达式的数组定义不是 VLA。所以,在你的代码中,

int other_array[sizeof(array)]

不是 VLA。

关于 sizeof 运算符结果,来自 C11,章节 §6.5.3.4,(强调我的

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. [...] otherwise, the operand is not evaluated and the result is an integer constant.

那是因为sizeof运算符的结果是常量表达式,所以不符合VLA条件,就像下面的声明:

int other_array[5];

也不能是变长数组。来自 C11 (N1570) §6.6/p6 常量表达式(强调我的前进):

An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts.

为了完整起见,sizeof 运算符并不总是导致常量表达式,尽管这只影响 post-C89 标准(在 C11 中 VLA 是可选的)。参考 §6.5.3.4/p2 sizeof_Alignof 运算符:

If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

在 ANSI C89 中 a.k.a。在 ISO C90 中,sizeof 运算符产生一个 整数常量 ,适用于数组维度。例如,函数调用不是。

我想再补充一点,因为我认为原样的代码存在一个可能被忽视的问题。

如果other_array声明为

double other_array[sizeof(array)];

它将既没有与array[]具有相同数量的元素,也没有相同的大小(这只适用于char的数组) .如果打算声明具有相同数量元素的第二个数组(无论类型如何),请使用:

double other_array[sizeof(array)/sizeof(*array)];