62331


以下のプログラムをVisualStudio2017, wandbox(gcc) で実行すると異なる結果になります。  
[wandbox](https://wandbox.org/permlink/GAcVt9qAAWz94YV7)

[code]

    // This file is a "Hello, world!" in C++ language by GCC for wandbox.
    #include <iostream>
    #include <cstdlib>
    #include <vector>
    #include <thread>
    namespace test {
    
        class Integer {
        public:
            explicit Integer() : value(0) {}
            int value;
        private:
        };
    
        class Data {
        public:
            explicit Data() = default;
            Integer i;
        private:
        };
    
        class Builder {
        public:
            explicit Builder() = default;
            Builder& set(Data& data) {
                data.i.value++;
                return *this;
            }
            Builder& print(std::vector<Data> vec) {
                for (Data data : vec)
                    std::cout << data.i.value << std::endl;
                return *this;
            }
        private:
        };
    }
    int main(int argc, char* argv[]) {
        test::Builder b;
        test::Data d;
    
        std::cout << d.i.value << std::endl;
        b.set(d).set(d).set(d).set(d).print(std::vector<test::Data>{d});
        return 0;
    }
    
[/code]

wandboxでは

[code]

    0
    4
    
[/code]

と表示されますが、  
VisualStudioでは

[code]

    0
    0
    
[/code]

と表示されてしまいます。  
なぜ挙動が違うのでしょうか？  
どちらかのコンパイラの不具合ですか？

環境  
VisualStudio  
* VisualStudio Community 2017  
* C++言語標準:ISO C++17 標準 (/std:c++17)

wandbox  
* gcc HEAD 10.0.1 20200115 (experimental)  
* 一つ下の 9.2.0 でも試しましたが同様の結果でした


CC BY-SA 4.0
2020-01-17T13:06:33.450
62329
2020-01-17T23:01:06.537
2020-01-17T23:01:06.537
19110
10677
question
c++ visual-studio gcc
VisualStudioとgccで挙動が違うのはなぜですか？

[code]

    b.set(d).set(d).set(d).set(d).print(std::vector<test::Data>{d});
    
[/code]

この式を

[code]

    auto s = b.set(d).set(d).set(d).set(d);
    s.print(std::vector<test::Data>{d});
    
[/code]

という順で評価して`4`を出力すべきか、

[code]

    auto v = std::vector<test::Data>{d};
    b.set(d).set(d).set(d).set(d).print(v);
    
[/code]

という順で評価して`0`を出力すべきかはC++言語仕様では定められていないため、実装依存の結果となります。

C++17で[厳密な式の評価順](https://cpprefjp.github.io/lang/cpp17/expression_evaluation_order.html)を定めていますが、今回の部分の順序にはあえて触れられていないそうです。


CC BY-SA 4.0
2020-01-17T14:20:18.160
62331
2020-01-17T14:20:18.160
4236
62329
answer