93755


例としてPoint構造体があり、それをC形式の配列に格納したいとします。  
下記のように各要素を丸括弧で定義した場合、コンパイルエラーは発生しませんが  
出力結果は期待通りとなりません。  
Printされる値は5要素のみで、順番もよく分からないものになってしまいます。

ちなみに、vectorを使った場合はコンパイルエラーになりました。

[code]

    #include <iostream>
    #include <vector>
    
    struct Point {
        int32_t x;
        int32_t y;
    };
    
    int main()
    {
        Point points[] {
            (-1, -1), ( 0, -1), ( 1, -1),
            (-1,  0), ( 0,  0), ( 1,  0),
            (-1,  1), ( 0,  1), ( 1,  1),
        };
    
        for (auto i = std::begin(points) , e = std::end(points); i != e; ++i)
        {
            printf("(%2d,%2d)\n", i->x, i->y);
        }
    
        /*
        std::vector<Point> points{ // コンパイルエラー
            (-1, -1), (0, -1), (1, -1),
            (-1,  0), (0,  0), (1,  0),
            (-1,  1), (0,  1), (1,  1),
        };
        */
    
        return 0;
    }
    
[/code]

[code]

    (-1,-1)
    (-1, 0)
    ( 0, 0)
    ( 1, 1)
    ( 1, 0)
    
[/code]

下記のように各要素を波括弧で初期化することで期待通り、9要素が出力されます。

[code]

    Point points[] {
        {-1, -1}, { 0, -1}, { 1, -1},
        {-1,  0}, { 0,  0}, { 1,  0},
        {-1,  1}, { 0,  1}, { 1,  1},
    };
    
[/code]

[code]

    (-1,-1)
    ( 0,-1)
    ( 1,-1)
    (-1, 0)
    ( 0, 0)
    ( 1, 0)
    (-1, 1)
    ( 0, 1)
    ( 1, 1)
    
[/code]

先に書いたように、各要素を丸括弧で囲んだ場合に起きている現象について  
理解が出来ない為、ご教示をお願いします。  
コンパイラになぜ5要素であると認識されるのでしょうか。

[動作環境]  
Microsoft Visual Studio Community 2022  
Version 17.4.4  
VisualStudio.17.Release/17.4.4+33213.308

[プラットフォームツールセット] Visual Studio 2022 (v143)  
[C++ 言語標準] ISO C++17 標準  
[C 言語標準] 既定 (従来のMSVC)


CC BY-SA 4.0
2023-02-08T01:59:12.100
93754
2023-02-08T04:07:43.627
2023-02-08T02:04:18.523
53943
53943
question
c++
C++ 構造体配列の初期化時に丸括弧を使用した場合に何が起きていますか


`(x, y)`
は[コンマ演算子](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%9E%E6%BC%94%E7%AE%97%E5%AD%90)
な式 `x, y` を括弧でくくって優先順位付けしたものと解釈されるので、提示 `points` の初期化は結局コンマの右要素だけが有効となり

[code]

    Point points[] {
        (-1, -1), ( 0, -1), ( 1, -1), // は -1, -1, -1 と読まれます
        (-1,  0), ( 0,  0), ( 1,  0), // は 0, 0, 0 と読まれます
        (-1,  1), ( 0,  1), ( 1,  1), // は 1, 1, 1 と読まれます
    };
    
[/code]

書き直すと

[code]

    Point points[] {
        -1, -1,
        -1, 0,
         0, 0,
         1, 1,
         1
    };
    
[/code]

１要素につき初期化子が２つ必要なのに、コード上は初期化子が９個しかないので最後の要素に対して初期化子 `0` が補われて提示の結果となります。


CC BY-SA 4.0
2023-02-08T02:20:01.880
93755
2023-02-08T02:20:01.880
8589
93754
answer


こちらの環境(g++)でコンパイルしたところ次の警告が出ています。

[code]

    qq2.cc: In function ‘int main()’:
    qq2.cc:12:10: warning: left operand of comma operator has no effect [-Wunused-value]
       12 |         (-1, -1), ( 0, -1), ( 1, -1),
          |          ^~
    qq2.cc:12:21: warning: left operand of comma operator has no effect [-Wunused-value]
       12 |         (-1, -1), ( 0, -1), ( 1, -1),
          |                     ^
    qq2.cc:12:31: warning: left operand of comma operator has no effect [-Wunused-value]
       12 |         (-1, -1), ( 0, -1), ( 1, -1),
          |                               ^
    qq2.cc:13:10: warning: left operand of comma operator has no effect [-Wunused-value]
       13 |         (-1,  0), ( 0,  0), ( 1,  0),
          |          ^~
    qq2.cc:13:21: warning: left operand of comma operator has no effect [-Wunused-value]
       13 |         (-1,  0), ( 0,  0), ( 1,  0),
          |                     ^
    qq2.cc:13:31: warning: left operand of comma operator has no effect [-Wunused-value]
       13 |         (-1,  0), ( 0,  0), ( 1,  0),
          |                               ^
    qq2.cc:14:10: warning: left operand of comma operator has no effect [-Wunused-value]
       14 |         (-1,  1), ( 0,  1), ( 1,  1),
          |          ^~
    qq2.cc:14:21: warning: left operand of comma operator has no effect [-Wunused-value]
       14 |         (-1,  1), ( 0,  1), ( 1,  1),
          |                     ^
    qq2.cc:14:31: warning: left operand of comma operator has no effect [-Wunused-value]
       14 |         (-1,  1), ( 0,  1), ( 1,  1),
    
[/code]


CC BY-SA 4.0
2023-02-08T02:31:02.743
93756
2023-02-08T02:31:02.743
35558
93754
answer


いちおう、Visual Studio においても[警告レベルを/Wall](https://learn.microsoft.com/ja-
jp/cpp/build/reference/compiler-option-warning-level?view=msvc-170)にすると

[code]

    ConsoleApplication3.cpp(11,11): warning C4548: expression before comma has no effect; expected expression with side-effect
    ConsoleApplication3.cpp(11,20): warning C4548: expression before comma has no effect; expected expression with side-effect
    ConsoleApplication3.cpp(11,29): warning C4548: expression before comma has no effect; expected expression with side-effect
    ConsoleApplication3.cpp(12,11): warning C4548: expression before comma has no effect; expected expression with side-effect
    ConsoleApplication3.cpp(12,20): warning C4548: expression before comma has no effect; expected expression with side-effect
    ConsoleApplication3.cpp(12,29): warning C4548: expression before comma has no effect; expected expression with side-effect
    ConsoleApplication3.cpp(13,11): warning C4548: expression before comma has no effect; expected expression with side-effect
    ConsoleApplication3.cpp(13,20): warning C4548: expression before comma has no effect; expected expression with side-effect
    ConsoleApplication3.cpp(13,29): warning C4548: expression before comma has no effect; expected expression with side-effect
    ConsoleApplication3.cpp(11,12): warning C5246: 'points': the initialization of a subobject should be wrapped in braces
    ConsoleApplication3.cpp(11,30): warning C5246: 'points': the initialization of a subobject should be wrapped in braces
    ConsoleApplication3.cpp(12,21): warning C5246: 'points': the initialization of a subobject should be wrapped in braces
    ConsoleApplication3.cpp(13,12): warning C5246: 'points': the initialization of a subobject should be wrapped in braces
    ConsoleApplication3.cpp(13,30): warning C5246: 'points': the initialization of a subobject should be wrapped in braces
    
[/code]

と警告されます。警告はそれぞれ

  * [C4548 コンマ前の式は無効です。有効な式を指定してください。](https://learn.microsoft.com/ja-jp/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4548?view=msvc-170)
  * [C5246 中かっこの不足に対する警告（個別ページはまだのよう）](https://learn.microsoft.com/ja-jp/cpp/overview/cpp-conformance-improvements?view=msvc-170#warning-for-missing-braces)

です。ただ、774RRさんとakira ejiriさんの回答を受けて調べただけで、通常、この警告を期待するのは難しいかなと思いました。


CC BY-SA 4.0
2023-02-08T04:07:43.627
93763
2023-02-08T04:07:43.627
4236
93754
answer