3

次のコードをコンパイルしようとすると、非常に奇妙なg++警告が表示されます。

#include <map>
#include <set>

class A {
public:

    int x;
    int y;

    A(): x(0), y(0) {}
    A(int xx, int yy): x(xx), y(yy) {}

    bool operator< (const A &a) const {
        return (x < a.x || (!(a.x < x) && y < a.y));
    }
};

struct B {
    std::set<A> data;
};

int
main()
{
    std::map<int, B> m;

    B b;

    b.data.insert(A(1, 1));
    b.data.insert(A(1, 2));
    b.data.insert(A(2, 1));

    m[1] = b;

    return 0;
}

出力:

$ g++ -Wall -W -O3 t.cpp -o /tmp/t
t.cpp: In function ‘int main()’:
t.cpp:14: warning: dereferencing pointer ‘__x.52’ does break strict-aliasing rules
t.cpp:14: warning: dereferencing pointer ‘__x.52’ does break strict-aliasing rules
/usr/lib/gcc/i686-redhat-linux/4.4.2/../../../../include/c++/4.4.2/bits/stl_tree.h:525: note: initialized from here

私には何の意味もありません。どのように解釈すればよいですか?投稿されたコードの何が問題になっているのかわかりません。

コンパイラの詳細を指定するのを忘れます:

$ gcc --version
gcc (GCC) 4.4.2 20091027 (Red Hat 4.4.2-7)
4

3 に答える 3

6

gcc 4.4 には、std::mapブレーク が厳密なエイリアス規則について誤って警告するというバグがあります。

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39390

コードは有効な C++ です。厳密なエイリアシングは、使用時にデフォルトで有効になっている最適化のサブセットを許可するだけです-O3

あなたの解決策は、-fno-strict-aliasingまたは別のバージョンの gcc でコンパイルすることです。

厳密なエイリアシングとは何かについて知りたい場合は、こちらで質問されています

于 2009-12-26T22:49:10.890 に答える
1

これを変更してみてください:

return (x < a.x || (!(a.x < x) && y < a.y));

の中へ:

return (x < a.x || (a.x == x && y < a.y));

また、g++ 3.4.2 の下であなたのバージョンと私のバージョンを使用してこれをコンパイルしましたが、すべて問題ありません。

于 2009-12-26T22:08:53.020 に答える
0

g++ のどのバージョンですか? g++ 4.3.2 はこれを問題なくコンパイルします。

于 2009-12-26T22:05:54.767 に答える