c++ - 我可以完全停止使用 "inline"吗?

标签 c++ compiler-construction inline

<分区>

因为它是否内联我的函数完全取决于编译器,我是否可以完全停止使用此关键字(假设它无论如何都会内联所有内容)?

最佳答案

您可以停止使用内联 作为优化技术

inline 基本上只有在您需要 ODR (One Definition Rule) 时才有用不申请。简而言之,您可以将函数标记为 inline 并直接在一个头文件中提供它们的定义,然后由多个翻译单元导入,而链接器不会对此发出提示:

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();
}

inline 关键字的存在(同样,不能保证编译器将执行内联)确保链接器将合并这些定义。

当然,为了使这个合并操作有意义,所有标记为inline 的函数的定义最终成为几个不同翻译单元的一部分必须相同。如果不是这种情况,您的程序有未定义的行为并且不需要诊断 - 这意味着您的编译器/链接器不需要检测这种不一致并告诉您有问题!

根据 C++11 标准的第 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.

请注意,您可以将相同的函数标记为 inline 并在不同的翻译单元中按字面定义两次,只要这些定义相同就可以了:

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();
}

但是,如果这两个定义不同,您将在代码中注入(inject) 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();
}

这就是为什么当您直接在通常的 #included 头文件中提供函数定义时,您通常将函数标记为 inline

另请注意,在类定义中直接内联定义的类成员函数会自动标记为inline

关于c++ - 我可以完全停止使用 "inline"吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15862636/

相关文章:

c++ - 找出哪个模块设置了处理器关联掩码

c++ - 如何从另一个类中访问一个类?

linux - ARM 工具链构建

html - 显示与 HTML 内联的元素?

php - 使用 php 将内联样式转换为 css

c++ - 为什么在 C++ 中显式声明 "inline"

c++ - 关于c++中的 'compare'函数

c++ - 在 GDB 中,在非调试二进制文件中的 namespace 或类中调用 C++ 函数的正确方法是什么?

c++ - vtable:底层算法

c++ - Windows 上的 LALR(1) 或 GLR - 当前的 Bison++/Flex++ 替代品?