【问题标题】:c++ strict-aliasing rules compile error with Qt and QLinkedList [duplicate]c ++严格别名规则使用Qt和QLinkedList编译错误[重复]
【发布时间】:2013-12-14 13:55:00
【问题描述】:
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&lt;int&gt;,并且定义了类解析器:

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 一起失败......我不知道为什么?任何人都看过这个错误信息并且任何人都知道这可能意味着什么?...更重要的是如何解决它?

【问题讨论】:

  • 另外这篇文章确实很好地描述了它:cellperformance.beyond3d.com/articles/2006/06/…
  • 是的,我在发布这个问题之前看到了那个帖子,并且 Qt 标头实际上正在使用该技术......所以这一定是不同的。
  • 如果你创建一个sscce.org,你可能会得到更好的帮助,这样其他人就可以编译它并戳它。顺便说一句,什么 Qt 版本?

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


【解决方案1】:

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

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

这里dpi 的别名。

这是c99中的>非法

我不知道 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。这会迫使 GCC 不基于此预期进行任何优化。

但无论如何,如果你做了错误的类型双关语,那么在 C 中它不是严格的 ISO C 代码。

(因此,如果它可以让您感到轻松,许多著名程序上的 C 代码都会使用 -fno-strict-aliasing 编译)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-11
    • 2019-01-29
    • 2015-01-17
    • 2015-05-31
    • 2015-10-15
    • 2017-02-25
    • 2018-12-14
    • 1970-01-01
    相关资源
    最近更新 更多