文字列リテラルの初期化から統一初期化構文と複合リテラルへの話

@melponnの「char* p = "hoge"; はできないけど char p[] = "hoge"; はできる」という旨の発言から、g++でコンパイルできる(int[]){1,2,3}はC++0xでどういう扱いなのかという話へ飛び移った3月10日深夜のC++TL。なお、(int[]){1,2,3}はC++0xの構文ではなく、g++でもC99の複合リテラルとして解析されているだろうという結論に至りました。
3
IGARASHI Shinji@無職 @s50

なんとなくC99とC++で混じっちゃってるだけのような気がしなくもないけどきっちり確認する気力がない

2010-03-11 02:48:45
めるぽん.c @melponn

そもそも文法違反じゃないのか?

2010-03-11 02:50:00
でちまるさん(実際かわいい) @decimalbloat

うーん、braced-init-listが何かの式として解釈されているよう…

2010-03-11 02:53:08
めるぽん.c @melponn

そういえば C++0x では enum の最後の要素にカンマが付いててもおっけーになったんだっけ。

2010-03-11 02:53:46
Yak! @yak_ex

std::initializer_list<int> じゃないですか? RT @melponn: { 1, 2, 3} 自体が何の型になるのかが仕様から分からない・・・

2010-03-11 02:54:42
でちまるさん(実際かわいい) @decimalbloat

もしかして (int[]) 型の値として{1,2,3}が認識されているから、これは実はキャストでも何でもない、ということか?どこにそんな文法を許容するという文言が書いたあるんや!!!

2010-03-11 02:55:24
IGARASHI Shinji@無職 @s50

というかg++ -pedantic -std=c++0x でふつうに error: ISO C++ forbids compound-literalsとかいわれますた

2010-03-11 02:57:48
Egtra (ysk-noh) @egtra

(int[]){1, 2, 3, 4}; (std::vector<int>){1, 2, 3, 4}; (std::array<int, 4>){1, 2, 3, 4}と並べてコンパイルが通ったら、そりゃ3つとも同じ構文だと思い込むよ……。

2010-03-11 03:00:49
めるぽん.c @melponn

@yak_ex 全部の braced-init-list がそうだとすると int[] なんかに代入できなくなりそうな気がー。

2010-03-11 03:01:03
Yak! @yak_ex

@DecimalBloat 全然ついていっていませんが、N3035 8.5.4p3 は関係してます?その辺は通り越した議論ですか?

2010-03-11 03:01:05
めるぽん.c @melponn

うーん、C++03 の仕様上だと無理だから新しい初期化リストの構文だと解釈されてるんだろうけど、std::initializer_list は int[] への変換を持ってないだろうし・・・いやほんとか?

2010-03-11 03:04:16
Egtra (ysk-noh) @egtra

あ、std::vector<int>{1, 2, 3, 4}; std::array<int, 4>{1, 2, 3, 4};でもコンパイル通る。ごめんなさい。

2010-03-11 03:05:09
Egtra (ysk-noh) @egtra

でもtypedef int arr_t[4]; arr_t{1, 2, 3, 4};もいけるぞ。int[]{1, 2, 3, 4};はエラー。

2010-03-11 03:06:40
でちまるさん(実際かわいい) @decimalbloat

@yak_ex 一応 declaration-statement において、 braced-init-list が登場できる文脈を調べたのですが、(int[]){1,2,3})がwell-formedである、と言える文言は見つからないです。

2010-03-11 03:06:44
IGARASHI Shinji@無職 @s50

ぼくのg++は4.3系なのでinitializer listsはついてないのでエラります

2010-03-11 03:10:13
でちまるさん(実際かわいい) @decimalbloat

@egtra arr_t{1,2,3}はあれですね、uniform initialization syntaxですね。

2010-03-11 03:10:56
IGARASHI Shinji@無職 @s50

つまりpedantic付けなけりゃ2つ合わせてなんかかっちょいい言語になるってことだ!ちがう!

2010-03-11 03:13:40
Yak! @yak_ex

@DecimalBloat simple type specifier の場合なら、5.2.3p3 だけど、int[] は simple type specifier じゃないだろってことですか。

2010-03-11 03:15:44
Egtra (ysk-noh) @egtra

やっと追い付いたかな。自分も5.2.3p3で納得した。

2010-03-11 03:24:11
Egtra (ysk-noh) @egtra

つまり(int[]){1, 2, 3}はC++0xの構文ではないと理解する。

2010-03-11 03:25:41
めるぽん.c @melponn

@egtra C++03 なマイ環境でコンパイルすると怒られました・・・

2010-03-11 03:29:21
Egtra (ysk-noh) @egtra

@melponn 自分が使っているg++ 4.4.1 (MinGW TDM)だと-pedantic付けない限り、-std=c++98でも(int[]){1, 2, 3}は警告1つ出さないです。

2010-03-11 03:33:37
めるぽん.c @melponn

@egtra あ、自分も (int[]){1, 2, 3}; だけだと怒られなくて、int n[] = (int[]){1, 2, 3}; ってやったら怒られました・・・。もうやだC++・・・

2010-03-11 03:35:33