【问题标题】:Forcing inline with a single macro in GCC, Clang and Intel Compiler?在 GCC、Clang 和英特尔编译器中强制内联单个宏?
【发布时间】:2015-01-22 14:10:27
【问题描述】:

我有一个函数需要在 C++11 的紧密循环中内联

我希望函数在与标头不同的文件中实现,并且仍然强制在使用它的任何地方内联它。另外,我想同时使用 clang、GCC 和 Intel 编译器进行编译。

充实需求。我正在寻找一个可以让我执行以下操作的宏:

#define force_inline <something here>

在标题中:

force_inline void foo();

而且我应该可以在实现文件中做到这一点:

void foo() {... Code.. }

为了清楚起见,我不想将代码放在我的标题中。我希望它们只包含函数的声明。

有没有办法使用适用于所有这些编译器的宏实现内联?

到目前为止我最好的解决方案是这个宏:

#define forceinline inline __attribute__((always-inline))

似乎ICC需要inline(与内联代码无关)和头部中的完整实现来保证函数的内联。

PS:是的,我已经测量了我的性能,并且我知道将函数内联比不内联更快。不,编译器不会为我这样做。

【问题讨论】:

  • 使用gcc -flto -O2 编译和链接。或者更好的是在你的头文件中将你的函数定义为static inline
  • 答案太多?我正在寻找同时适用于所有三个编译器的宏。
  • @BasileStarynkevitch: 明确一点:我不想在头文件中实现函数,只需要声明
  • 这是显而易见的,即使答案是“否”。
  • Per N4140 [dcl.fct.spec]/4:“内联函数应在使用 odr 的每个翻译单元中定义,并且在每种情况下都应具有完全相同的定义 (3.2 )。”如果您将单个定义放在头文件中并将其包含在 ODR 使用它的每个 TU 中,则更容易避免 ODR 违规。将定义复制到多个实现文件中当然会产生同样的效果,但我认为它更肮脏。

标签: c++ c++11 gcc clang icc


【解决方案1】:

根据定义,内联函数的代码(由编译器)包含在它被调用的每个位置。

这意味着编译器在构建调用者编译单元时需要能够访问函数的代码。这在技术上是可行的,但并不容易且难以扩展。请注意,如果您仅分发头文件和库,则意味着使用您的组件的编译器必须从库中检索代码!

如果由编译器实现,则意味着您不会像常规函数那样从头文件中的代码中受益(更改 CPP 文件将需要根据头文件重新编译所有文件,即使它没有t 改变)。唯一的好处是有一个不包含代码的标题(这仍然是一件好事)。

我知道目前唯一可用的解决方案是 GCC 的链接时间优化,因此无法满足您使用 clang 和 icc 的要求:https://gcc.gnu.org/wiki/LinkTimeOptimization 对于那些具有特定选项的编译器,可能存在类似的东西,它们需要编写依赖于编译器的代码来支持它。

解决方案 1: 您可以在标题中保留一个“干净的类”而无需任何实现,并将内联函数放在类之外(但仍在标题中)。标题中仍然有定义,但它与声明明显分开,因此对可读性的伤害较小。 (这是我个人更喜欢的解决方案)

解决方案 2: 如果您真的只想要标头中的声明,另一种缓解问题的方法是将您的代码分成 3 个文件而不是 2 个文件: - 仅包含接口的 .h 文件 - 包含内联函数并包含在 .h 文件中的 .i 文件 - 包含其余代码的 .cpp/.cc 文件

显然这也有缺点,因为您的代码现在被分隔在两个不同的文件中...

如果您发现我遗漏的问题以及您在这些建议中看到的问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    相关资源
    最近更新 更多