Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++ 的inline 远不止如此 #109

Open
Mq-b opened this issue Oct 13, 2023 · 3 comments
Open

C++ 的inline 远不止如此 #109

Mq-b opened this issue Oct 13, 2023 · 3 comments

Comments

@Mq-b
Copy link

Mq-b commented Oct 13, 2023

在内联函数中,

  • 所有函数定义中的函数局部静态对象在所有翻译单元间共享(它们都指代相同的在某一个翻译单元中定义的对象)
  • 所有函数定义中所定义的类型同样在所有翻译单元中相同。
命名空间作用域的内联 const 变量默认具有外部链接(这点与非内联非 volatile 的有 const 限定的变量不同) (C++17 起)


在内联函数中,

所有函数定义中的函数局部静态对象在所有翻译单元间共享(它们都指代相同的在某一个翻译单元中定义的对象)
所有函数定义中所定义的类型同样在所有翻译单元中相同。
命名空间作用域的内联 const 变量默认具有外部链接(这点与非内联非 volatile 的有 const 限定的变量不同)

(C++17 起)
inline 关键词的本意是作为给优化器的指示器,以指示优先采用函数的内联替换而非进行函数调用,即并不执行将控制转移到函数体内的函数调用 CPU 指令,而是代之以执行函数体的一份副本而无需生成调用。这会避免函数调用的开销(传递实参及返回结果),但它可能导致更大的可执行文件,因为函数体必须被复制多次。

因为关键词 inline 的含义是非强制的,编译器拥有对任何未标记为 inline 的函数使用内联替换的自由,和对任何标记为 inline 的函数生成函数调用的自由。这些优化选择不改变上述关于多个定义和共享静态变量的规则。

由于关键词 inline 对于函数的含义已经变为“容许多次定义”而不是“优先内联”,因此这个含义也扩展到了变量。

(C++17 起)

即使是 C 语言的 inline 也有比这多的多的意思。编译器优化层面的理解反而是最简单的。

不管是否进行内联,内联函数都保证下列语义:

任何拥有内部链接的函数都可以声明成 static inline ,没有其他限制。

一个非 static 的内联函数不能定义一个非 const 的函数局部 static 对象,并且不能使用文件作用域的 static 对象。

若非 static 函数声明为 inline ,则必须在同一翻译单元中定义它。不使用 extern 的内联定义不会对外部可见,而且不会阻止其他翻译单元定义同一函数。这使得 inline 关键词成了 static 外另一种在头文件定义函数的方式,可以由同一程序的多个翻译单元包含该头文件。

若函数在一些翻译单元中声明为 inline ,它就不需要在处处皆声明为 inline :至多一个单元会提供常规的非 inline 非 static 函数,或是声明为 extern inline 的函数。称此翻译单元提供外部定义。为避免未定义行为,若在表达式中使用拥有外部链接的函数名,则程序中必须存在一个外部定义,见一个定义规则

内联函数的地址始终是外部定义的地址,但当以此地址进行函数调用时,调用内联定义(若存在于翻译单元中)还是外部定义是未指定的。定义于内联定义中的 static 对象与定义于外部定义中的 static 对象有别:

inline 关键词是从 C++ 吸收的,但在 C++ 中,若函数声明为内联,则它必须在每一个翻译单元声明为内联,而且每一个内联函数都必须有准确相同的定义( C 中,定义可以相异,而依赖这些差异仅导致未指定行为)。另一方面, C++ 允许非 const 的函数局域 static 对象,而且所有来自一个内联函数不同定义版本的函数局部 static 对象都相同,但它们在 C 中不同。

@w272628569
Copy link

w272628569 commented Oct 13, 2023 via email

@DaweiWangBIT
Copy link

DaweiWangBIT commented Oct 13, 2023 via email

@w540665710
Copy link

w540665710 commented Oct 13, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants