在C中,为什么const变量不能用作数组大小初始值设定项?

在以下代码中,const int不能用作数组大小:

const int sz = 0; typedef struct { char s[sz]; } st; int main() { st obj; strcpy(obj.s, "hello world"); printf("%s", obj.s); return 0; } 

在C中, const -qualified变量不是常量表达式 1 。 常量表达式可以在编译时计算 – 数字文字如103.14159 ,字符串文字如"Hello"sizeof表达式,或某些表达式由10 + sizeof "Hello"

对于文件范围(在任何函数体外)的数组声明或作为structunion类型的成员,数组维必须是常量表达式。

对于auto数组(在函数体内声明的非static数组), 可以使用变量或表达式,其值在运行时之前是未知的,但仅限于C99或更高版本。


  1. C ++在这方面有所不同 – 在该语言中, const -qualified变量确实算作常量表达式。

这是因为在C const实际上意味着只读 。 引用C FAQ 1.18和1.19 :

const限定符实际上意味着“只读”; 一个如此限定的对象是一个不能(通常)分配给它的运行时对象。 因此,const限定对象的值在该术语的完整意义上不是常量表达式,并且不能用于数组维度,案例标签等。 (在这方面,C与C ++不同。)当您需要真正的编译时常量时,请使用预处理器#define(或者可能是枚举)。

参考文献:ISO Sec。 6.4 H&S Secs。 7.11.2,7.11.3第226-7页

处理它有两种方法:

  1. 使用#define而不是const
  2. 使用enum { sz = 12 };

以一种非常简单的方式,因为编译器必须在编译时知道数组的维度,并且因为你可以在运行时初始化const variable ,所以你不能这样做。 因此,静态声明的数组的大小必须常量表达式,const variable不是它。 对于常量表达式,您应该使用宏( #define )或enum 。 这明确适用于您的情况(在文件范围内),如果您使用最低标准c99