我有一些关于 VLA 及其行为的概念需要澄清。
自 C99 以来的 AFIK 可以将 VLA 声明为本地范围:
int main(int argc, char **argv)
{
// function 'main' scope
int size = 100;
int array[size];
return 0;
}
但在全局范围内是禁止的:
const int global_size = 100;
int global_array[global_size]; // forbidden in C99, allowed in C++
int main(int argc, char **argv)
{
int local_size = 100;
int local_array[local_size];
return 0;
}
上面的代码在 C99 中声明了一个 VLA,因为 const
修饰符不会创建编译时值。在 C++ 中 global_size
是编译时值,所以 global_array
不会成为 VLA。
我需要知道的是:我的推理是否正确?我描述的行为是否正确?
我也想知道:为什么VLA不允许在全局范围内?它们在 C 和 C++ 中都被禁止吗?为什么数组在全局和局部范围内的行为不同?
原文由 PaperBirdMaster 发布,翻译遵循 CC BY-SA 4.0 许可协议
是的,您的推理是正确的,这就是 C 和 C++ 看待这些不同形式的数组声明和定义的方式。
正如其他人已经说过的那样,在全局范围内具有真正可变长度(非
const
)的 VLA 很难理解。评估顺序是什么,例如,如果长度表达式将引用不同编译单元的对象? C++ 没有 VLA,但它在文件范围内动态初始化对象。如果您必须依赖评估顺序,这已经让您非常头疼。这为 C 留下了关于包含
const
限定对象的长度表达式的小差距,这是不允许的。这是因为此类对象不被 C 标准视为“整数常量表达式”。这可能会在未来的版本中发生变化,但到目前为止,C 委员会认为没有必要允许这样的事情:有enum
常量在 C 中扮演这个角色。它们唯一的限制是它们仅限于int
在 C 中,如果也有它们就好了size_t
。