为什么使用const不允许变量大小的对象初始化

jit*_*hsk 4 c compiler-construction const

这是错误的,因为可能无法初始化可变大小的对象

int size = 4;
int array[size] = {1};
Run Code Online (Sandbox Code Playgroud)

size是一个变量,但编译器在创建时是否知道它的值array(size在编译时没有为初始值4分配?)?让我们size改变之后,为什么会出现这个问题呢?我的意思是,这些是连续的指令,什么可能改变size数组声明之前的值?

第二个问题:为什么不允许这样做:

const int size = 4;
int array[size] = {1};
Run Code Online (Sandbox Code Playgroud)

我宣称size是一个常数.我知道const!=只读,并且声明size为宏是正确的方法.但是,如果我保证编译器使用const我不会改变它的值size,为什么不允许?

小智 6

第一个问题的答案是"因为语言规范是这样说的".虽然编译器可能能够推断出数组的大小,但这样做需要一些静态分析,当数组大小不是编译时常量表达式时,这不是一件容易的事.

至于为什么不允许初始化VLA:能想到的一个原因是,直到运行时才知道它们将包含多少个元素,因此VLA可能比其初始化列表更短,这将调用未定义的行为.但是我无法确定这是否是(真正的原因)之一.

第二个问题:为什么不允许这样做:

允许的,除非的编译器的编写者生活在一个洞穴中(例如,微软的工程师们 - 他们的C编译器是一个罕见的例子,广泛使用的编译器仍然不支持C99,15年后它的标准化.任何现代的,体面的C编译器都应该允许您使用C99中存在的可变长度数组.已经实现C11的编译器可能会也可能不会选择支持VLA(因为它是最新标准的可选功能).

  • @KVM:一个`const`限定的变量不是C中的*常量表达式*(编译时常量); 它只是一个运行时变量,其值在初始化后可能无法修改.一个*常量表达式*将是一个数字文字,一个扩展为数字文字的宏,一个仅由数字文字或宏组成的算术表达式,或一个扩展为这种表达式的宏,例如`#define ARR_SIZE WORDS + SPACES + 1` (2认同)