c - 在声明 VLA 的同一序列点中启动 VLA 的大小部分是否有效?

标签 c variable-length-array sequence-points

this post ,OP 包含有很多错误的代码,但是 1 行让我特别好奇,因为我无法查找任何东西,不允许它。这是具体的行:

int n = 100000, arr[n];

是否保证了声明和初始化的顺序?

所以在这里我假设甚至可能发生在 arr 被声明时 n 没有被初始化的情况,这显然不是一件好事。

但我在手头的 iso/iec 9899 草案中找不到关于此的任何声明,既未声明未定义也未定义。

这就是我假设的未定义行为吗? 或者是?

无论哪种方式,应用于该结果的规则是什么?5

编辑:

这对 C99 也有效吗?

最佳答案

简而言之:您的代码是正确的。这是你的前提是错误的。这两个声明不是“在同一个序列点”。 (作为旁注:一个点不可能有任何东西,只有两点之间,点是无量纲的)。

详情:

标准的6.8.2给出了复合语句的语法,它是每个函数体的基础:

compound-statement:
    { block-item-listopt }
block-item-list:
    block-item
    block-item-list block-item
block-item:
    declaration
    statement

此处相关的是 block 项目。如图所示,它可以是声明声明。这意味着声明 不是声明。您显示了一个声明,因此, 在这里不是运算符,而是分隔init-declarators(一个声明符 可选地使用初始化程序,语法参见 6.7)。在 声明符 之后(顺便说一句,在可选的初始化程序之前)有一个序列点。

6.7.6p3: A full declarator is a declarator that is not part of another declarator. The end of a full declarator is a sequence point. If, in the nested sequence of declarators in a full declarator, there is a declarator specifying a variable length array type, the type specified by the full declarator is said to be variably modified. Furthermore, any type derived by declarator type derivation from a variably modified type is itself variably modified.

关于“执行顺序”:其实是留给执行的。但标准要求遵循抽象机。序列点是基本的排序概念。


这个问题实际上与 VLA 没有直接关系,而是与一般声明符有关。在不引用所有先前版本的部分的情况下,行为在所有版本中都是相同的,因为否则类似 int i = 3, k = i; 的内容也将不起作用(它确实起作用)。

关于c - 在声明 VLA 的同一序列点中启动 VLA 的大小部分是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38327837/

相关文章:

c++ - 在 CRichEditCtrl 上使用表情符号时内存泄漏

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

c++ - 在 C++11 环境中使用 VLA

c++ - 在条件运算符中使用对象两次会产生 UB 吗?

c++ - 序列点从何而来?

c - MIPS 代码周期时间

c - 替换字符串中的一个字符

c++ - 重新分配而不释放旧内存

c++ - C++中使用变量初始化数组

c++ - 这段代码定义明确吗?