在 [N1570 草案的 6.7.9 (11) 中,与 C99 的 6.7.8 (11) 相同] 中规定
标量的初始值设定项应为单个表达式,可选择用大括号括起来。对象的初始值是表达式的初始值(转换后);应用与简单赋值相同的类型约束和转换,将标量的类型作为其声明类型的非限定版本。
通过在
char *ptr={'R','E','D','\0'};
您违反了“应”要求并调用了未定义的行为 (4 (2)):
如果违反了出现在约束或运行时约束之外的“应”或“不应”要求,则行为未定义。
顺便说一句,这种特殊类型的未定义行为通常主要表现为编译器忽略除第一个表达式之外的所有表达式 - 除了生成
warning: excess elements in scalar initializer|
并将代码视为
char *ptr = {'R'};
然后,这毫不奇怪会导致
warning: initialization makes pointer from integer without a cast|
因为'R'
是整数而不是指针。
另一方面,
char *ptr = "RED";
非常好,因为数组(1) "RED"
在初始化中被转换为指向其初始元素的指针,就像它用于赋值一样。
(1)字符串字面量是数组,而不是指针,如 6.4.5 (6) 节所述:
在翻译阶段 7 中,将一个字节或值为零的代码附加到由一个或多个字符串文字产生的每个多字节字符序列。然后使用多字节字符序列来初始化一个静态存储持续时间和长度刚好足以包含该序列的数组。对于字符串文字,数组元素的类型为 char,并使用多字节字符序列的各个字节进行初始化。对于 UTF-8 字符串文字,数组元素具有 char 类型,并使用多字节字符序列的字符进行初始化,如 UTF-8 编码。
(宽字符串字面量是wchar_t[N]
,char16_t[N]
或类型的数组char32_t[N]
,取决于它们是否以L
,u
或. 为前缀U
。)