【问题标题】:How to detect 'strict aliasing' at compile time?如何在编译时检测“严格别名”?
【发布时间】:2010-10-18 00:43:32
【问题描述】:

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

我想为不关心的处理器和编译器维护旧的和非严格别名准备的代码路径。它似乎更快。

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

【问题讨论】:

    标签: c++ c optimization pointers


    【解决方案1】:

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

    一种半便携的方法是从您的 Makefile 中 - 为别名和非别名版本定义不同的目标,并为别名版本定义您自己的 STRICT_ALIASING(或其他)预处理器符号。

    【讨论】:

      【解决方案2】:
      【解决方案3】:

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

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

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

      【讨论】:

      • 这是错误的。 C 和 C++ 都允许在同一类型的变量之间使用别名,但 C 和 C++ 都不允许使用不同类型的别名(即 GCC 中的严格别名优化)。
      【解决方案4】:

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

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

      -Wstrict-aliasing --- 此选项仅在“-fstrict-aliasing”为 积极的。它警告代码 可能会破坏严格的别名规则 编译器用于 优化。警告不 抓住所有情况,但确实试图 抓住更常见的陷阱。它是 包含在“-Wall”中。是等价的 到'-Wstrict-aliasing=3'

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


      顺便说一句,akauppi 在 cmets 中说:

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

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

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

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

      【讨论】:

      • 对不起,你错了。 'restrict' 为特定指针启用严格的别名优化。我问如何检测该优化是否是全局的,自动的,应用于 all 指针。抱歉,-1。
      猜你喜欢
      • 1970-01-01
      • 2020-02-13
      • 2016-08-16
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2013-12-14
      • 2011-04-05
      • 2020-07-25
      相关资源
      最近更新 更多