考虑在C中定义一个char指针。然后指令:
char *str
str = "Hello World!"
没有产生任何错误。假设我对C和指针的了解几乎不可接受,为什么这个指令是正确的?不是吗:
str = &("Hello World!");
引用C11
,第6.3.2.1章
除非它是
sizeof
运算符、_Alignof
运算符或一元&
运算符,或是用于初始化数组的字符串文字,该表达式具有类型为"的数组被转换为类型为"指向类型"的指针的表达式到数组对象的初始元素,并且不是左值。[….]
这里,字符串文字,基本上是char
FootNote的数组类型,当用作赋值运算符的RHS时,会衰减到指向数组第一个元素的指针。
因此,LHS(指针类型(和RHS(派生指针类型(是兼容的,这是赋值运算符所要求的,并且语句是有效的。
也就是说,
str = &("Hello World!");
无效,因为&("Hello World!");
的类型为char (*) [13]
(指向13个char
的数组的指针(,并且不是分配的LHSchar *
的兼容类型。
脚注:
引用C11
,§6.4.5
在翻译阶段7中,每个多字节都会附加一个值为零的字节或代码由一个或多个字符串文字产生的字符序列。78(多字节字符然后使用序列初始化静态存储持续时间和长度的数组足以包含序列。对于字符串文字,数组元素具有键入char,并使用多字节字符的各个字节进行初始化序列[….]
字符串文字"Hello World!"
是char [13]
类型的匿名对象,即13个字符的数组,它在所有上下文中都隐式衰减为指向数组第一个字符(char *
!(的指针,除非数组作为&或者在CCD_ 14/CCD_。
str = &("Hello World!")
(可以在没有括号的情况下写入str = &"Hello World!"
(特别是不正确,因为&("Hello World!")
的结果属于*char (*)[13]
类型,即指向13个字符的数组的指针!
GCC会将其诊断为
test.c:3:9: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
str = &"Hello World!";