在 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)];
我的印象是可变大小数组声明在 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)];