ケース 1:
std::valarray<int> data = {1,4,0,2,5};
std::valarray<bool> exp_mask = data <= 2;
std::mask_array<int> marr1 = data[mask];
marr1 = 10;
ケース 2:
std::valarray<int> data = {1,4,0,2,5};
data[data <= 2] = 11; // 7
ケース 3:
std::valarray<int> data = {1,4,0,2,5};
std::mask_array<int> marr2 = data[data <= 2];
marr2 = 12;
ケース 1 とケース 2 は両方とも期待どおりに機能します (データは適切に変更されます)。ただし、ケース3は恐ろしく信頼できないほど失敗します(私にとってはセグメンテーション違反です)。gdb でさらに調べると、内部に格納されたマスクが一時的なdata <= 2
valarray のバッファーを指しているように見えますが、これは行 2 の後で破棄されます。次に、行 3 で書き込みを行うと、マスクは完全にガベージであり、それにインデックスを付けようとします。データのマスクされた値を設定することは、未定義の動作です。
この動作が許可されている理由を標準のどこにも見つけることができません (標準は valarray について奇妙にあいまいです)。これはlibstdc ++の偽物ですか、それともこの結果とその理由を期待する必要がありますか?
テストされたコンパイラ設定:
- g++4.8.2 -O0 -g -std=c++0x
- clang++ -O0 -g -std=c++11
libstdc++ の私のバージョンは 3.4.19 だと思います (これをたどって見つけました)