c ++严格别名规则使用Qt和QLinkedList编译错误

时间:2013-11-28 13:36:05

标签: c++ qt templates compiler-errors g++

In file included from /usr/local/Qt/linux-g++/include/QtCore/QLinkedList:2,
  from /home/bamboo/Packages/Parser.h:17,
  from /home/bamboo/Packages/Module.cpp:6:
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h: In member function 'void QLinkedList<T>::clear() [with T = int]':
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:294: error: dereferencing pointer 'y' does break strict-aliasing rules
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:293: note: initialized from here
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:294: error: dereferencing pointer 'y' does break strict-aliasing rules
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:293: note: initialized from here

在大行中,类Module包含一个成员模板,如:Parser<int>,并且定义了类解析器:

template <typename T> class Parser
{
   // some stuff
   QLinkedList<T> stuff;
};

这段代码很好地与gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2很好地编译,并且与g++ (Debian 4.4.5-8) 4.4.5失败......我不明白为什么?任何人都看到了这个错误信息,任何人都知道这可能意味着什么?...更重要的是如何解决它?

1 个答案:

答案 0 :(得分:0)

别名意味着指针int *i指向与double *d相同的地址。 所以,如果

int i = 5;
int *pi = &i:
double *d = pi;

此处d是别名pi

这是在c99&gt;非法&lt;

我不知道c ++究竟是如何对待它的,但我无法想象它是受欢迎的。

如果您想测试一个有趣的代码,请尝试不同优化级别的代码。

您将获得与gcc 4.2

不同的结果
uint32_t anint;

int main(int arg, char** argv)
{
    foo ((uint64_t *)&anint);
    return 0;
}

void foo (uint64_t *dblptr)
{
    anint = 88;
    *dblptr = 86;
    dosmthng (anint);
}

void dosmthng (uint32_t val)
{
    printf ("%d\r\n", val);
}

如果你做-O2或更高,输出将是88.因为编译器希望你尊重严格别名规则并期望*dblptr从未在这段代码中使用过,并且jsut取消了该行。

如果以任何方式看不到别名的工作方式,您可以为编译器提供参数-fno-strict-aliasing。这迫使海湾合作委员会不根据这一期望进行任何优化。

但是无论如何,如果你做错了类型惩罚,那么它不是严格的ISO C代码。

(所以,如果它可能让你感到轻松,很多着名程序上的C代码都会被编译为-fno-strict-aliasing