const char *cval = "nothing"; // This is right.
int *ival = {1, 2, 3, 4}; // This is wrong.
为什么第一个是对的,但第二个是错的?
答案 0 :(得分:6)
之所以如此,是因为语言规范是这样说的(对每种语言都是独立的)。
在C和C ++中,字符串文字是一个无名的对象,一个左值。由于它是一个对象,您可以使用指针指向它。同时{1, 2, 3, 4}
只是一个不代表对象的语法结构。它只是形成聚合初始化器语法的正式字符序列。
同时,在C语言中(自C99起)有一个名为复合文字的功能,它允许形成聚合类型的无名对象。例如,以下初始化有效
int *ival = (int []) {1, 2, 3, 4};
这基本上是第一个声明的“int数组”对应物。所以,从C的角度来看,你的第二个声明是“错误的”,仅仅是因为你使用了不正确的语法。
答案 1 :(得分:5)
char *cval = "nothing"; // This is right.
字符串文字有特殊处理 - 编译器知道将文本“nothing \ 0”放在某个(不可变)内存中,类型为char[]
,然后数组衰减为char*
可以复制到cval
(对于C ++ 03及更早版本,在C ++ 11中,您应该使用const char*
)。这与......形成鲜明对比。
int *ival = {1, 2, 3, 4}; // This is wrong.
...编译器不希望将{1,2,3,4}存储在只读内存中 - 它只需要:
用于赋值给数组 - 将值复制到本地声明的对象中的连续数组位置(但当ival
为int*
时,没有为要放入的值分配内存)
对于构造函数接受initializer_list
的类,创建一个并调用该构造函数。