const int i = 100;
int *j = &i;
int array[i] = {0};
这合法吗?我读到某个地方没有& i,i和100将被添加到符号表中,但由于& i,存储被强制为i,100将在编译时存储在i中;因此,编译器将无法读取i(来自存储)的值来分配数组 - 这是真的吗?
答案 0 :(得分:6)
在C90和C99中,定义int array[i] = {0};
不合法(无论您使用i
做什么)。
在文件范围声明的数组必须有一个整数常量表达式作为length(6.5.4.2或6.7.5.2,§2,resp。)
如果定义具有功能/块范围,则它仍然是非法的,因为
答案 1 :(得分:4)
int *j = &i;
应为const int *j = &i;
。在那之后,您的代码是合法的。
编辑:在C ++中
答案 2 :(得分:4)
绝对没有理由为什么变量不能同时具有编译时常量值和物理存储。因此,它取决于语言的标准。
C ++允许常量整数为编译时常量。 C没有。一些编译C的C ++编译器将混合并匹配两种语言的某些功能,因此编译器可能会接受它作为标准的扩展。
答案 3 :(得分:1)
这合法吗?我读到某个地方没有& i,i和100将被添加到符号表中,但由于& i,存储被强制为i,100将在编译时存储在i中;因此,编译器将无法读取i(来自存储)的值来分配数组 - 这是真的吗?
以下是C99标准的语言:
6.7.3类型限定符
...
3与限定类型关联的属性仅对表达式有意义 是左值。 114)
114)实现可能会将const
对象放在volatile
的只读区域中 存储。此外,如果其地址是,则实现不需要为这样的对象分配存储 从未使用过。
所以,有点真实,但在这种情况下并不真正相关。编译器不 为i
创建存储以在其他地方使用其值;它可以简单地使用值为100
的立即操作数代替i
。无论哪种方式,行int j = &i;
都是不必要的。
i
不是整数常量表达式,这意味着它不是编译时常量(在C中; C ++在这方面是不同的);它是一个运行时变量,其值在其生命周期内可能不会被修改。
从C99开始,您可以使用运行时变量指定数组大小,即使是一个声明为const
的变量,所以
const int i = 100;
int array[i];
将array
分配为int
的100个元素数组。但是,您无法将初始化程序与VLA一起使用,因此int array[i] = {0};
不有效。
同样,C ++是不同的,根本不支持VLA。但是由于i
被声明为const
,C ++将其视为编译时常量,这意味着您的代码应该是合法的C ++(无论如何它都是为我构建的)。
更多来自C99:
6.7.5.2数组声明符
...
4如果大小不存在,则数组类型为不完整类型。如果大小为*
而不是。{ 作为表达式,数组类型是未指定大小的可变长度数组类型, 它只能用于具有函数原型范围的声明; 124)这样的数组是 尽管如此,完整的类型。如果size是一个整型常量表达式,并且元素类型具有已知的常量大小,则数组类型不是可变长度数组类型; 否则,数组类型是可变长度数组类型 ...
6.7.8初始化
...
3要初始化的实体的类型应为未知大小的数组或对象类型 这不是可变长度数组类型。
124)因此,*只能用于非定义的函数声明(见6.7.5.3)。