如何在编译时检测'严格别名'?

时间:2009-04-07 11:11:03

标签: c++ c optimization pointers

'Strict aliasing'优化需要特别注意源代码,s.a。使用union而不是指针强制转换。有没有办法检测使用预处理器指令(#if / else)编译器是否正在尝试进行此类优化?

我想为那些不关心的处理器和编译器维护旧的和非严格别名准备的代码路径。看起来更快。

编辑:GCC predefined macros似乎没有任何关于别名的内容。换句话说,我对gcc 4.x最感兴趣,但也是一般解决方案(似乎不存在)。

4 个答案:

答案 0 :(得分:3)

完全依赖于实现 - 您需要检查特定编译器的文档。在提出这样的问题时,最好提一下你正在使用的编译器。

执行此操作的半便携式方法来自您的Makefile - 为别名和&定义不同的目标。 unaliased版本并为别名版本定义自己的STRICT_ALIASING(或其他)预处理器符号。

答案 1 :(得分:2)

答案 2 :(得分:1)

没有通用的解决方案。最接近的是#ifdef __cplusplus,因为标准C ++允许编译器假设指向不同类型的指针没有别名(除非它们是char *)。即使在简单的场景中也会发生这种情况:

void (int *foo, float *bar) {
  *foo++;
  *bar = 0; // Can safely be scheduled between the load and store of foo.
}

因此,“严格混叠”并不是真正的最优化; “容忍未定义的行为”是一种悲观。

答案 3 :(得分:1)

据我所知,没有用于检测严格别名的预处理程序指令。

如果您正在使用gcc的“-Wall”,那么编译器会警告您可能违反严格别名规则的代码。

  

-Wstrict-aliasing ---此选项仅在'-fstrict-aliasing'时有效   活性。它警告代码   可能会破坏严格的别名规则   编译器正在使用的   优化。警告没有   捕获所有情况,但确实尝试   抓住更常见的陷阱。它是   包含在'-Wall'中。它是等价的   到'-Wstrict-aliasing = 3'

如果您正在处理的代码很重要,那么您可以在gcc中禁用-fstring-aliasing。或者如果您不想禁用严格别名,我建议查看asm输出以确保编译器没有进行您不想要的危险优化。


顺便说一句,akauppi在评论中说:

  

'restrict'启用严格别名   针对特定指针的优化。

restrict关键字不直接“启用...优化”,而是为编译器提供更多信息,并且额外信息间接帮助编译器确定它是否可以应用特定的优化技术。

TI's DSP compiler documentation中对restrict关键字的一个很好的解释:

为了帮助编译器确定内存依赖性,您可以限定a 带有restrict关键字的指针,引用或数组。 restrict关键字是 一个类型限定符,可以应用于指针,引用和数组。它的用途 代表程序员在指针范围内的保证 声明指向的对象只能由该指针访问。任何 违反此保证会导致程序未定义。这种做法有帮助 编译器优化代码的某些部分,因为别名信息 可以更容易确定。