文字列リテラルの char[] 初期化

本の虫: C++0xでは、文字列リテラルから非constなポインタへの変換はできない に char* への変換はダメっていうのがありますが、char[] への変換はどうなの?という話です。

const char cs[] = "bjarne";
char s[] = "hage";

cs は当然 OK ですけど、s はどうなんでしょう。
"hage" は const char[ ] 型*1なので、もし s に代入できるとしたら const char[ ] から char[ ] への変換ができるということで、そこから array-to-pointer の変換が行われて char* に変換できても不思議ではないです。

char s[] = "hage"; // これが OK なら
char* p = "flush"; // これも OK なんじゃないの?

そこら辺が気になったので調べてみました。


するとこんなのが。

A char array (whether plain char, signed char, or unsigned char), char16_t array, char32_t array, or wchar_t array can be initialized by a narrow character literal, char16_t string literal, char32_t string literal, or wide string literal, respectively, or by an appropriately-typed string literal enclosed in braces. Successive characters of the value of the string literal initialize the elements of the array. [ Example:

char msg[] = "Syntax error on line %s\n";

shows a character array whose members are initialized with a string-literal. Note that because ’\n’ is a
single character and because a trailing ’\0’ is appended, sizeof(msg) is 25. ―end example ]

§8.5.2¶1

char 配列とかは適切な文字列リテラルで初期化できるって書いてますね。
しかもこの項は変換ではなくて初期化の部分なので、const char[ ] から char[ ] への変換ができるわけではないため array-to-pointer 変換で char* になったりする心配も無さそうです。


あとその辺眺めてるときに気がついたのですが、

If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be value-initialized (8.5). [ Example:

struct S { int a; char* b; int c; };
S ss = { 1, "asdf" };

initializes ss.a with 1, ss.b with "asdf", and ss.c with the value of an expression of the form int(), that is, 0. ―end example ]

§8.5.1¶7

"asdf" を char* に変換しようとしてるので、間違ってるっぽいですね。

*1:[ と ] の間にスペースがあるのは、自動リンク停止記法と判断されてしまうからです。テラウザス