由于完全由编译器决定是否内嵌函数,所以我可以完全停止使用这个关键字(假设它将内联所有内容).
解决方法
内联基本上只有当您想要ODR (One Definition Rule)不适用时才有用.简而言之,您可以将函数标记为内联,并直接在一个头文件中提供其定义,然后由多个翻译单元导入,而无需链接器就此提出以下问题:
foo.hpp
inline int foo() { return 42; }
Foo.cpp中
#include "foo.hpp" // <== THE LINKER WOULD COMPLAIN IF foo() WERE NOT inline,// because its definition is imported also in main.cpp void bar() { int x = foo(); }
main.cpp中
#include "foo.hpp" // <== THE LINKER WOULD COMPLAIN IF foo() WERE NOT inline,// because its definition is imported also in foo.cpp int main() { std::cout << foo(); }
内联关键字的存在(再次不保证编译器将执行内联)可确保链接器将合并这些定义.
当然,为了使这个合并操作是有意义的,标记为内联的功能的所有定义都必须是相同的.如果不是这种情况,您的程序具有Undefined Behavior,并且不需要诊断 – 这意味着您的编译器/链接器不需要检测到这种不一致,并告诉您有什么不对!
根据C11标准的第3.2 / 4段,其实:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used
in that program; no diagnostic required. The definition can appear explicitly in the program,it can be found
in the standard or a user-defined library,or (when appropriate) it is implicitly defined (see 12.1,12.4 and
12.8). An inline function shall be defined in every translation unit in which it is odr-used.
请注意,您可以在不同的翻译单元中具有标记为内联和字面定义两次的相同功能,只要这些定义相同即可.
Foo.cpp中
inline int foo() // Has the same body in main.cpp,no problem! { return 42; }
main.cpp中
inline int foo() // Has the same body in foo.cpp,no problem! { return 42; } int main() { std::cout << foo(); }
但是,如果两个定义不同,您将在代码中注入UB,如以下示例所示:
Foo.cpp中
inline int foo() { return 42; // <== WATCH OUT! Different body in main.cpp }
main.cpp中
inline int foo() { return -42; // <== WATCH OUT! Different body in foo.cpp } int main() { std::cout << foo(); }