问题描述
为什么以下有效:
#define MAX 100
char MY_ARRAY[MAX];
但以下没有:
int MAX_2 = 200;
char MY_ARRAY_2[MAX_2];
这是来自 Compiler Explorer
的示例。对我来说有趣的是在定义最终的字符数组之前,事情看起来应该可以工作——所有整数都在数据中定义...
解决方法
在数组的声明中
#define MAX_VALUE 100
char MY_ARRAY[MAX_VALUE];
数组的大小使用了一个整数常量表达式。
在本声明中
int MAX_VALUE=100;
char MY_ARRAY[MAX_VALUE];
声明了一个变长数组。但是您不能声明具有静态存储持续时间的可变长度数组(特别是在文件范围内)。如果编译器支持变长数组,您可以在块作用域中声明这样的数组。
即使您将在变量 const
的声明中使用限定符 MAX_VALUE
,如
const int MAX_VALUE = 100;
它不会根据 C 标准中的定义生成整数常量表达式。
相反,你可以写
enum { MAX_VALUE = 100 };
char MY_ARRAY[MAX_VALUE];
来自 C 标准(6.6 常量表达式)
6 整数常量表达式 117) 应具有整数类型且应 只有整数常量、枚举常量的操作数, 字符常量,结果为整数的 sizeof 表达式 常量和作为直接操作数的浮点常量 铸件。整数常量表达式中的强制转换运算符只能 将算术类型转换为整数类型,除非作为 操作数到 sizeof 运算符。
And(6.7.6.2 数组声明符)
4 如果大小不存在,则数组类型为不完整类型。如果 大小是 * 而不是表达式,数组类型是 未指定大小的变长数组类型,只能使用 在具有函数原型作用域的声明或类型名称中;这样的 数组仍然是完整的类型。 如果大小是整数 常量表达式并且元素类型具有已知的常量大小, 数组类型不是变长数组类型;否则, 数组类型是变长数组类型。(变长数组 是实现不需要支持的条件特性;看 6.10.8.3.)
和
2 如果标识符被声明为具有可变修改的类型,则它 应为普通标识符(如 6.2.3 中所定义),没有 链接,并且具有块作用域或函数原型作用域。 如果 标识符被声明为具有静态或线程的对象 存储期间,不得为变长数组类型。