K162

Starwalker, Stardust.

0%

关于 [Error] array bound is not an integer constant before ']' token

错误的定义

起因是我在 main() 函数外定义了一个全局变量和数组:

1
2
int n = 10;
int array[n];

然后,编译器就不留情面地报错了:

[Error] array bound is not an integer constant before ‘]’ token

如果是 C,对数组进行类似错误的定义,会出现如下的报错:

[Error] variably modified ‘array’ at file scope

加上 const 限定符

一般而言,C/C++ 的编译器在编译时,一个数组的长度往往要求是静态已知的。因此,如果数组 array[n] 长度是借助一个变量 n 来确定,那么可以加上 const 限定符:

1
2
int const n = 10;	// 加上 const
int array[n];

或者换种方式:

1
2
#define size 10	// 宏定义
int array[size];

《C Primer Plus》中有阐述道,C90 新增的 const 关键字是 用于限定一个变量为只读。同时中文版的译者还在其中注解道:在 C 语言中,用 const 类型限定符声明的是变量,不是常量。1

变长数组(variable-length array, VLA)

在 C 的 C99 标准中,引入了变长数组的特性,即允许使用变量表示数组的维度:

1
2
int n = 10;
int array[n]; // 一个变长数组

但最终,C11 把变长数组变成了一个可选特性。其实,变长数组的“变”也不过是在创建数组时,可以使用变量指定数组的维度。至于想修改已创建的数组长度——tan90!(不存在的!)

变长数组相对而言是新特性,所以目前完全支持这一特性的编译器也不多。

遵守规范

有人在 StackOverflow2 上指出,如果把最上面对变量和数组的错误定义,放在 main() 函数里头,虽然没有报错(这也恰恰符合我的印象),但也是不合规范的:

Both examples are ill-formed in C++. If a compiler does not diagnose the latter, then it does not conform to the standard.

You use a language extension that allows runtime length automatic arrays. But does not allow runtime length static arrays. Global arrays have static storage.

参考资料

[1] Stephen Prata.C Primer Plus[M].北京:人民邮电出版社,2019:78.
[2] eerorika, Why should global array size be an integer constant?