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

时间:2016-07-12 11:38:10

标签: c variable-length-array sequence-points

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

int n = 100000, arr[n];

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

所以在这里我假设甚至可能发生narr被宣布时没有被初始化,这看起来很不好。

但是我无法在iso / iec 9899草案中找到任何关于此的陈述,既没有说明未定义也没有定义它。

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

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

修改

这对C99也有效吗?

1 个答案:

答案 0 :(得分:2)

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

细节:

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

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

这里的相关内容是块项目。如图所示,它可以是语句声明。这意味着声明不是声明。您显示声明,因此,不是此处的运算符,而是分隔 init-declarators 声明符可选初始化,请参阅6.7语法。并且在声明符之后(在可选的初始化器之前,btw。)之前有一个序列点。

  

6.7.6p3:完整声明者是不属于另一个声明者的声明者。 完整声明符的结尾是序列点。如果在完整声明符的嵌套的声明符序列中,有一个声明符指定了一个可变长度的数组类型,那么整个声明符指定的类型被称为可变地修改。此外,通过可变修改类型的声明符类型派生派生的任何类型本身都会被可变地修改。

关于"执行顺序":这实际上留给了实现。但标准要求遵循抽象机器。序列点是基本的排序概念。

问题实际上与VLA没有直接关系,而是一般的声明者。如果不引用所有先前版本的部分,则所有版本的行为都是相同的,因为否则int i = 3, k = i;之类的内容也不起作用(确实如此)。