2

サンプルコードは次のとおりです。

X * makeX(int index) { return new X(index); }
struct Tmp {
    mutable int count;
    Tmp() : count(0) {}
    const X ** getX() const { 
        static const X* x[] = { makeX(count++), makeX(count++) };
        return x; 
    }
};

これにより、静的配列の構築で CLang ビルド 500 の未定義の動作が報告されます。この投稿を簡略化するために、カウントは静的ではありませんが、何も変更されません。私が受け取っているエラーは次のとおりです。

test.cpp:8:44: 警告: 'count' への複数のシーケンスされていない変更 [-Wunsequenced]

4

3 に答える 3

10

C++11 ではこれで問題ありません。初期化子リストの各句は次の句の前に並べられるため、評価は明確に定義されています。

歴史的に、句は順序付けされていない可能性があるため、 の 2 つの順序付けられていない変更によりcount、未定義の動作が発生します。

(ただし、コメントに記載されているように、それは当時でも明確に定義されていた可能性があります-おそらく、各句が完全式であり、各完全式の終わりにシーケンスポイントがあることを意味するものとして標準を解釈できます.時代遅れの言語の細かい点についての議論は歴史家に任せる.)

于 2013-11-08T14:59:13.097 に答える
2

この場合、,はシーケンス ポイントではなく、配列の要素の初期化における区切り記号のように機能します。

つまり、シーケンス ポイントのないステートメントで同じ変数を 2 回変更しています (変更の間)。


編集: @MikeSeymour に感謝: これはC++03以前の問題です。のように思えますが、この場合C++11は評価の順序が定義されています。

于 2013-11-08T14:56:13.220 に答える