6.7.9 (11) [N1570 ドラフトの、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