如何解读 g++ 警告

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)

它在没有-O3的情况下工作吗?(谷歌告诉我它发生在-O2和-O3)。如果不行,那么可能是int的operator<不是const int... - e8johan
是的,它在没有 -O3 的情况下编译通过且没有警告。 - user66363
3个回答

6

gcc 4.4存在一个错误,即std :: map在严格别名规则下中断不正确地发出警告

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

您的代码是有效的C ++。 严格别名仅允许使用-O3时启用的一些优化的子集。

您的解决方案是使用-fno-strict-aliasing或不同版本的gcc进行编译。

如果您想知道什么是严格别名,请参见此处的问题


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下编译了这个程序,一切都正常。


0

使用哪个版本的g++?g++ 4.3.2可以编译这个代码而不会报错。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接