this answer 的评论部分中的一个参数促使我问这个问题。
在下面的代码中,bar
指向一个变长数组,所以sizeof
是在运行时而不是编译时确定的。
int foo = 100;
double (*bar)[foo];
争论的焦点是当操作数是可变长度数组时,是否使用 sizeof
计算其操作数,使得 sizeof(*bar)
在 时成为未定义行为bar
未初始化。
使用 sizeof(*bar)
是否是未定义的行为,因为我取消引用了一个未初始化的指针?当类型为可变长度数组时,sizeof
的操作数是否实际求值,还是仅确定其类型(sizeof
通常如何工作)?
编辑:每个人似乎都在引用 this passage来自 C11 草案。有谁知道官方标准是不是这样写的?
最佳答案
是的,这会导致未定义的行为。
在 N1570 6.5.3.4/2 中我们有:
The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. 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.
现在我们有一个问题:*bar
的类型是不是变长数组类型?
由于 bar
被声明为指向 VLA 的指针,因此取消引用它应该会产生一个 VLA。 (但我没有看到具体的文字说明是否这样做)。
注意:可以在这里进行进一步的讨论,也许可以说 *bar
的类型 double[100]
不是 VLA.
假设我们同意*bar
的类型实际上是一个VLA类型,那么在sizeof *bar
中,表达式*bar
是评估。
bar
此时是不确定的。现在查看 6.3.2.1/1:
if an lvalue does not designate an object when it is evaluated, the behavior is undefined
由于 bar
不指向对象(由于不确定),评估 *bar
会导致未定义的行为。
关于c - `sizeof` 的操作数是否使用 VLA 评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32985424/