2011-11-09 8 views
16

C++03C++11の両方で完全に有効であることが判明しました。`char`配列を初期化するのに有効な文字列リテラルを含む初期化子はなぜですか?

charの配列がchar const*ではないため、私はそれが期待できません。また、brace-initialiserには、それぞれの「アイテム」に互換性のあるタイプが必要です。 1つのアイテムがあり、それはchar const*ではなく、charです。

この初期設定を有効にするにはどうすればよいですか?そしてそれがそうであることについての理論的根拠はありますか?


同様に、char c[] = {"aa"};コンパイル、及び出力 "aa" でc結果を印刷します。

私はchar c[]{"a"}はもちろん、C++ 11で有効であると期待されるが、それは同じではありません!同様に、char c[] = {'a'}は、両方とも明らかであり、char c[] = "a"である。

+0

あなたは 'char c [] = {" aa "};'を試したことがありますか? –

+0

@VJo:有効です。 –

+0

なぜあなたはそれが無効であると思いますか?あなたが求めていることは本当にはっきりしません。それはそれを禁止する規則がないので有効です。それを禁止すると思われるルールはどれですか? – jalf

答えて

3

スカラ型は、構造体や配列と同様に中括弧で初期化することもできます。

struct S { int x, char c }; 
S s = {5, 'a'}; 

int arr[] = {5, 6, 7}; 

/* (my guess) out of consistency */ 
int z = { 4 }; 

と文字列リテラルは、文字列のポインタと

char arr[] = "literal"; 
char* ptr = "another"; 

に割り当てることができるので、あまりにもchar arr[] = { "literal" };を許可するようにフィッティングようです。

+0

Aha!私はそれが理にかなっていると思う。本当にスカラーなのですが、私は集計イニシャライザーでハングアップしていましたか? (あなたが私のドリフトを取得した場合)私たちはスカラーの一種としてリテラルを「見ている」のですか? –

+0

はい、少なくとも、それはどのように私はそれが起源だと思います。しかし、私はCの標準委員会ではない:)ちょうど推測... – Pieter

+0

申し分なく;ありがとう! –

5

これは必ずしも直感的ではありませんが、です。

[2003: 8.5.2/1]:A char array (whether plain char , signed char , or unsigned char) can be initialized by a string-literal (optionally enclosed in braces); a wchar_t array can be initialized by a wide string-literal (optionally enclosed in braces); successive characters of the string-literal initialize the members of the array. [..]

[n3290: 8.5.2/1]: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.

委員会がなぜこのようにしたのか説明できません。

+0

さて、これは素敵な感じです。char^["abc"}; '... '、' char b [] = {"abc"}; 'と書くことができます。 –

+0

@KerrekSB:私はそれがどのように役に立つか見ていない! –

+0

「委員会がなぜこのようにしたのか説明することはできませんが、未回答のまま質問に追加することはできます。確かに、ほとんどの回答は「Standardがそう言っているでしょうが、なぜ「なぜ?」と言うかもしれません。 –

0

私はそれがCの互換性のためだと思いますか?実際にはT x = { value of T };は他のタイプのTにも適用されます。 C99標準では、

6.7.8/11: The initializer for a scalar shall be a single expression, optionally enclosed in braces.

6.7.8/14: An array of character type may be initialized by a character string literal, optionally enclosed in braces.

6.7.8/15: An array with element type compatible with wchar_t may be initialized by a wide string literal, optionally enclosed in braces.

私はなぜCがこれを持っているのかわかりません。

+0

プロットが濃くなります。 –

+0

2番目の文はどういう意味ですか? 'int main(){int i = 3; int * ptr =&i; int x [] = {ptr}; } ' - >'エラー: 'int *'から 'int'への無効な変換(期待どおり、 'char 'で最初に期待されていたように...)ここでのポインタの使用はすべてリテラルとにかく、あなたは私が何を意味するか知っています...私はかなりそれが 'char'の特別なケースだと確信しています)。 [編集:心配しないでください。ちょうどあなたが言ったことを明確にするために、引用符全体が正確に理解されています。私は "種類"よりも "種類"と言っていたでしょう:)] –

+0

@ TomalakGeret'kal:私は 'int * x = {ptr};'を意味します。ポインタを暗黙的に配列に変換することはできません。文字列リテラルは配列型です(§6.4.5)。 – kennytm