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

时间:2022-09-08 07:20:27

I was under the impression that variable-size array declarations were not possible in C89. But, when compiling with clang -ansi I am able to run the following code:

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

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

What is going on here? Is that not considered a variable-size array declaration?

这是怎么回事?这不是一个可变大小的数组声明吗?

3 个解决方案

#1


5  

That is because result of sizeof operator is constant expression, so it does not qualify for VLA, just like the following declaration:

这是因为sizeof算符的结果是常量表达式,所以不符合VLA,如下声明:

int other_array[5];

cannot be variable length array either. From C11 (N1570) §6.6/p6 Constant expressions (emphasis mine going forward):

也不能是可变长度数组。从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.

整数常量expression117)应该具有整数类型,并且应该只有整数常量、枚举常量、字符常量、结果是整数常量的sizeof表达式、_Alignof表达式和浮点常量,它们是类型转换的直接操作数。

For sake of completeness, the sizeof operator does not always results into constant expression, though this only affects post-C89 standards (in C11 VLAs were made optional). Referring to §6.5.3.4/p2 The sizeof and _Alignof operators:

为了完整性起见,sizeof运算符并不总是会导致常量表达式,尽管这只会影响后c89标准(在C11 VLAs中是可选的)。指§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.

如果操作数的类型是可变长度数组类型,则计算操作数;否则,操作数不计算,结果为整数常数。

#2


8  

In ANSI C89 a.k.a. ISO C90, the sizeof operator yields an integer constant, which is suitable for array dimensions. Function calls, for example, are not.

在ANSI C89,即ISO C90中,sizeof运算符会产生一个整数常数,它适用于数组维数。例如,函数调用不是。

I'd like to add another remark, since I believe the code as-is has a problem that might get overlooked.

我还想补充一点,因为我认为代码本身存在一个可能被忽略的问题。

If the other_array is declared as

如果将other_array声明为

double other_array[sizeof(array)];

it will neither have the same number of elements, nor the same size (that would only be true for array of char) as array[]. If the intent is to declare a second array with the same number of elements (regardless of type), use this:

它的元素数量和大小(这只适用于char数组)都不会与array[]相同。如果目的是声明具有相同数量元素(无论类型)的第二个数组,请使用以下命令:

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

#3


3  

First, let's see the criteria for an array (not being) a VLA. C11 doc, chapter §6.7.6.2,

首先,让我们看看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; [...]

[…]如果大小是整数常量表达式,元素类型有已知的常量大小,则数组类型不是可变长度数组类型;[…]

Coming to your case, sizeof is a compile-time operator, so it produces a value that is considered compile time constant expression. An array definition, whose size is specified as a compile time constant expression is not a VLA. So, in your code,

在您的例子中,sizeof是一个编译时操作符,因此它产生一个被认为是编译时常量表达式的值。数组定义,其大小指定为编译时常量表达式,不是VLA。所以,在你的代码中,

int other_array[sizeof(array)]

is not a VLA.

不是一个射电望远镜。

Regarding the sizeof operator result, from C11, chapter §6.5.3.4, (emphasis mine)

关于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运算符产生其操作数的大小(以字节为单位),这可能是一个表达式或类型的圆括号名称。[…否则,操作数不被计算,结果是一个整数常数。

#1


5  

That is because result of sizeof operator is constant expression, so it does not qualify for VLA, just like the following declaration:

这是因为sizeof算符的结果是常量表达式,所以不符合VLA,如下声明:

int other_array[5];

cannot be variable length array either. From C11 (N1570) §6.6/p6 Constant expressions (emphasis mine going forward):

也不能是可变长度数组。从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.

整数常量expression117)应该具有整数类型,并且应该只有整数常量、枚举常量、字符常量、结果是整数常量的sizeof表达式、_Alignof表达式和浮点常量,它们是类型转换的直接操作数。

For sake of completeness, the sizeof operator does not always results into constant expression, though this only affects post-C89 standards (in C11 VLAs were made optional). Referring to §6.5.3.4/p2 The sizeof and _Alignof operators:

为了完整性起见,sizeof运算符并不总是会导致常量表达式,尽管这只会影响后c89标准(在C11 VLAs中是可选的)。指§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.

如果操作数的类型是可变长度数组类型,则计算操作数;否则,操作数不计算,结果为整数常数。

#2


8  

In ANSI C89 a.k.a. ISO C90, the sizeof operator yields an integer constant, which is suitable for array dimensions. Function calls, for example, are not.

在ANSI C89,即ISO C90中,sizeof运算符会产生一个整数常数,它适用于数组维数。例如,函数调用不是。

I'd like to add another remark, since I believe the code as-is has a problem that might get overlooked.

我还想补充一点,因为我认为代码本身存在一个可能被忽略的问题。

If the other_array is declared as

如果将other_array声明为

double other_array[sizeof(array)];

it will neither have the same number of elements, nor the same size (that would only be true for array of char) as array[]. If the intent is to declare a second array with the same number of elements (regardless of type), use this:

它的元素数量和大小(这只适用于char数组)都不会与array[]相同。如果目的是声明具有相同数量元素(无论类型)的第二个数组,请使用以下命令:

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

#3


3  

First, let's see the criteria for an array (not being) a VLA. C11 doc, chapter §6.7.6.2,

首先,让我们看看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; [...]

[…]如果大小是整数常量表达式,元素类型有已知的常量大小,则数组类型不是可变长度数组类型;[…]

Coming to your case, sizeof is a compile-time operator, so it produces a value that is considered compile time constant expression. An array definition, whose size is specified as a compile time constant expression is not a VLA. So, in your code,

在您的例子中,sizeof是一个编译时操作符,因此它产生一个被认为是编译时常量表达式的值。数组定义,其大小指定为编译时常量表达式,不是VLA。所以,在你的代码中,

int other_array[sizeof(array)]

is not a VLA.

不是一个射电望远镜。

Regarding the sizeof operator result, from C11, chapter §6.5.3.4, (emphasis mine)

关于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运算符产生其操作数的大小(以字节为单位),这可能是一个表达式或类型的圆括号名称。[…否则,操作数不被计算,结果是一个整数常数。