2009-12-26 92 views
3

試圖編譯下面的代碼時,我有一個很奇怪的G ++警告:如何解釋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 

它沒有任何SENCE我在所有。我應該如何解讀?我沒有看到發佈的代碼有什麼問題。

忘記指定編譯器的詳細信息:

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

它沒有-O3工作嗎? (谷歌告訴我,它發生在-O2和-O3)。如果沒有,是否可以是運算符 e8johan 2009-12-26 22:03:43

+0

是的,它編譯時沒有警告,沒有-O3。 – UncleO 2009-12-26 22:49:26

回答

6

GCC 4.4具有這樣的std ::地圖 休息 錯誤地發出警告嚴格走樣規則的錯誤。

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

你的代碼是有效的C++。嚴格別名僅允許使用-O3時默認啓用的優化子集。

您的解決方案是使用-fno-strict-aliasing或不同版本的gcc進行編譯。

如果你對什麼是嚴格的別名是好奇的,that has been asked here

0

哪個克++版本? g ++ 4.3.2編譯這個沒有抱怨。

+0

傻,我看到:4.4.2。 – 2009-12-26 22:08:50

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您的版本和我的版本是一切ok。