あめだまふぁくとりー

Boost.Graphとかできますん

GCC 4.9.1 で List-initialization の評価順が直っていた

List-initialization におけるリストの各要素の評価順は左から右に評価されるように規定されています. しかし, GCC 4.9.0 以前では List-initialization でコンストラクタが呼び出される場合は正しい順序で引数が評価されていませんでした.

#include <iostream>

int f(int i)
{
    std::cout << i << std::endl;
    return i;
}

struct S {
    S(int, int, int) {}
};


int main()
{
    std::cout << "1 2 3 の順に出力されるはず" << std::endl;
    int a[3] = {f(0), f(1), f(2)};
    (void)a;

    std::cout << "出力順は規定されていない" << std::endl;
    S(f(0), f(1), f(2));

    std::cout << "1 2 3 の順に出力されるはず" << std::endl;
    S{f(0), f(1), f(2)};
}

GCC 4.9.0 での出力::

1 2 3 の順に出力されるはず
0
1
2
出力順は規定されていない
2
1
0
1 2 3 の順に出力されるはず
2
1
0

GCC 4.9.1 ではこのバグが修正されたので, 正しい順序で評価されます.

1 2 3 の順に出力されるはず
0
1
2
出力順は規定されていない
2
1
0
1 2 3 の順に出力されるはず
0
1
2

melpon.org

バグ報告されてから修正されるまで 2 年半以上もかかった息の長いバグでした.

51253 – [C++11][DR 1030] Evaluation order (sequenced-before relation) among initializer-clauses in braced-init-list