我想我完全理解inlineC++中关键字的含义.具体来说,它意味着两个只有半相关的东西:
inline.因此,您可以在多个TU中定义相同的功能符号,而不会在链接时出错.这允许在标题中定义函数.call指令功能符号的地址.我可以理解这两个含义必然在一个方向上相关:2必须暗示1.#2要求函数定义可用于调用该函数的所有TU.因此,函数定义必须存在于多个TU中.因此,需要放宽ODR以避免链接器错误.
但我的问题是关于另一个方向 - 为什么语言设计为1必须暗示2?
在某些情况下和某些设计决策中,希望能够放松函数的ODR似乎是合理的,而不向编译器建议它应该实际内联函数代码.如果我有一个函数,我想通过头文件分发,我必须将其标记为inline放松ODR(#1).但是现在我被迫进入#2,即使我有特定的知识,在性能方面,该功能不适合内联.
我的理解是模板功能不存在这种不必要的含义.ODR会自动放宽模板功能(必须如此).这允许我inline仅用作性能建议.
我知道在头文件中分发函数,而不是像静态库,可能是一个坏主意.但作为一名程序员,我有可能知道自己在做什么,我希望这种灵活性.我有模板功能的灵活性,为什么不模板功能呢?
或者是否有一种可移植的方式来放松ODR而不建议内联函数?例如,在MSVC上你可以这样做:
__declspec(noinline) inline void Foo() {}
Run Code Online (Sandbox Code Playgroud)
这里inline放宽了ODR,但__declspec(noinline)要求编译器实际上没有内联调用.但是__declspec(noinline)不便携.
谢谢!
为什么语言设计为1必须暗示2?
该语言的目的不是这样.
语言根本无法明确指定函数应该或不应该内联扩展 - 既不强制也不优选.
该语言也没有指定内联声明暗示内联扩展的首选项.然而,编译器实现者发现让程序员表达他们对内联扩展的偏好是有用的.可能是由于缺乏明确表达该偏好的标准方法,编译器实现者已选择让内联声明暗示偏好.
由于该语言缺乏表达内联扩展偏好的标准方法,因此只能使用特定于实现的语言扩展来表达.
但是
__declspec(noinline)不便携.
您可以使用平台检测宏将其移植到具有类似属性的所有实现.GCC和Clang有__attribute__((noinline)).
另一种方法是根本不在意.编译器仍然可以选择忽略它所隐含的偏好.如果内联扩展会很昂贵(因为函数很大),智能编译器应该避免扩展它.
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |