【发布时间】:2016-01-25 22:51:15
【问题描述】:
2011 年标准明确规定...
6.7.6.2 数组声明符
- 如果大小是一个不是整数常量表达式的表达式:如果它出现在一个 在函数原型范围内声明,它被视为被替换为
*;否则, 每次对其进行评估时,它的值都应大于零。每个实例的大小 可变长度数组类型在其生命周期内不会改变。如果大小表达式是sizeof运算符的操作数的一部分,并且更改大小表达式的值不会影响运算符的结果,则未指定是否 计算大小表达式。
这是人为的,但下面的代码似乎是合理的。
size_t vla(const size_t x) {
size_t a[x];
size_t y = 0;
for (size_t i = 0; i < x; i++)
a[x] = i;
for (size_t i = 0; i < x; i++)
y += a[i % 2];
return y;
}
Clang 似乎为它生成了合理的 x64 程序集(没有优化)。显然索引一个零长度的 VLA 没有意义,但是越界访问会调用未定义的行为。
为什么零长度数组未定义?
【问题讨论】:
-
C 也不允许零长度的非 VLA;不允许它们作为 VLA 是一致的。 GCC(因此也有 clang)具有允许零长度数组的扩展。你可以争论这是否好。
-
“显然索引零长度 VLA 没有意义,但越界访问会调用未定义的行为。” - 示例中都没有发生。
-
@KarolyHorvath 我的想法是索引零长度的东西已经被禁止了。与空列表或零长度向量类似,只要值没有被索引(语言已经禁止),零长度数组对我来说是有意义的。
-
@JonathanLeffler 有趣的是,std::array in C++ does special case 的长度为零。
-
@Jason,该语言不禁止索引零长度数组-语法允许!只有越界访问的结果是UB。这适用于所有数组,与类型或大小无关。
标签: c arrays variable-length-array