c++ - 是否保证只有一个非内联内联函数的拷贝?

标签 c++ inline one-definition-rule inlining

如果我声明一个大的内联函数,而编译器选择将它编译为一个独立的函数,是否保证程序中只有一个非内联内联函数的拷贝,或者编译器最终可能会在不同的翻译单元中创建此函数的多个非内联拷贝?

或者,以几乎肯定会引起咬牙切齿的方式重新表述:在预处理时间不是问题的情况下,在头文件中内联定义一个大型方法是一种能够重用该方法的有效方法无需在单独的翻译单元中编译/链接代码?

最佳答案

你需要在这里非常具体,因为你要求保证。 C++ 标准对程序行为做出保证,而不是对实现做出保证,即使那样也不是为了防止恶意编译器而编写的。许多实现细节都受到行为的有效约束。但不完全是。

编译器可以自由地在您的可执行文件中嵌入任何函数的 2^17 个不同拷贝,无论是否内联。这将毫无意义,但标准并没有禁止它!静态变量的值和地址必须共享,因为这是可观察的,并且如果 C++ 代码可以访问它们,则指向每个函数的所有函数指针都必须比较相等(它们可以具有地址的不同二进制表示,只是改变执行 ==! 的意义。

这会发生吗?不,但你要求保证。 C++ 标准为实现者留下了巨大的空间。实现质量意味着现代编译器不会经常做愚蠢的事情。

实际上,在每个使用它的 .o 文件中创建一个内联函数。它被标记为特殊(“弱”)。静态链接时,这些拷贝中除了一个以外的所有拷贝都将被丢弃。保留哪一个取决于链接顺序,并且可能因构建而异(尤其是部分构建)。只有一份静态局部变量以类似的方式保存。在运行时必须比较所有指向函数或静态局部变量的指针。

动态链接导致某些编译器在构建到 dll 中时将其丢弃。加载 .so 时,其他编译器会查看符号是否已加载,如果已加载,则不加载 .so 中的拷贝。动态链接是函数的多个拷贝最有可能继续存在并被访问的情况。如果这种情况没有发生,您就清楚了,如果是,请对其进行测试。 C++ 标准没有描述动态链接。

关于c++ - 是否保证只有一个非内联内联函数的拷贝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40040371/

相关文章:

C++ 泛型链表独立类

jquery - 克隆背景图像并在文件名中添加括号

c++ - 单一定义规则是否强制创建单个静态函数变量?

android - 如何在通过 Android.mk 构建的存档上运行 ranlib?

c++ - 将函数定义放在头文件中

c++ - 命名空间范围内的 constexpr 变量,有和没有显式内联定义

c++ - 在析构函数中删除单链接列表的正确方法是什么?

C++ 数组中最大的数字。正面及负面

c++ - win32 - .dll 中的对话框

android - 如何在C++内联成员函数中添加Android调试功能(LOGE、LOGW...)?