c - `sizeof` 的操作数是否使用 VLA 评估?

标签 c sizeof variable-length-array

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/

相关文章:

c - gcc-arm编译器为同一个源文件生成不同的目标文件

c - 为什么空声明适用于具有 int 参数的定义但不适用于 float 参数?

c - 如何获取时区的相应位置

c - 已安装检查 c 但未找到 "check.h"

c - 为什么 sizeof ('a' ) 在 C 中是 4?

c - 将数组作为函数指针传递并使用 sizeof() 运算符

c - 如何找到数组的大小(从指向数组第一个元素的指针)?

C99 如何将简单指针转换为可变长度的多维数组?

c++ - C++14 中的可变长度数组?

c - 使用可变长度数组有任何开销吗?