gpt4 book ai didi

C++:当动态库中的内联函数发生变化时要重新编译什么?

转载 作者:搜寻专家 更新时间:2023-10-31 02:09:43 26 4
gpt4 key购买 nike

我有两个动态库和一个可执行文件:

  • libOtherLibrary.so
    • 这是一个由其他人编写的现有开源库。
  • libMyLibrary.so
    • 这是我自己的库,它依赖于 libOtherLibrary.so
  • 执行程序
    • 这是我自己的可执行文件,它依赖于这两个库。

作为查看何时调用特定函数的测试,我将打印语句添加到 libOtherLibrary.so内联函数(代码细节无关紧要) :

template<class T>
inline void className<T>::clear() const
{
Info << "Hello World!" << endl; // My message!
if (isTmp() && ptr_)
{
if (ptr_->unique())
{
delete ptr_;
ptr_ = 0;
}
else
{
ptr_->operator--();
ptr_ = 0;
}
}
}

然后我重新编译了 libOtherLibrary.so,然后重新编译了 libMyLibrary.so。最后我重新链接(所以没有重新编译)exe

结果是任何对 className<T>::clear() 的调用在 libMyLibrary.so 中启动使用此内联方法的 实现,而对 className<T>::clear() 的任何调用由 libOtherLibrary 发起。因此使用了实现。

当我随后决定也重新编译 exe(然后链接它)时,结果总是使用实现。


我的问题是:有人可以向我解释为什么 exe 需要重新编译,而不是仅重新链接吗?

也就是函数className<T>::clear()的内联libOtherLibrary.so 应该发生在 libMyLibrary.so 的编译阶段,不是吗?毕竟,它是包含在 libMyLibrary.so 中的一个调用 className<T>::clear() 的函数。 .然后我希望链接 exe 就足够了,因为 exe 不会调用这个特定的内联函数。链接器将单独处理任何更改的 ABI 兼容性。

最佳答案

My question is: Can someone explain to me why exe required recompilation, rather than relinking only?

因为,对于您的特定用例,如果没有它,您将招致 ODR violation 的愤怒.


The result was that any call to className<T>::clear() initiated in libMyLibrary.so used the old implementation of this inline method, whereas any call to className<T>::clear() initiated by libOtherLibrary.so used the new implementation.

当你有一个函数模板时说:

template<class T>
inline void className<T>::clear(){
....
}

它是ODR used在多个翻译单元(.cpp 文件)中。它的实例化将在每个这样的翻译单元中定义,因为函数模板是隐式的inline .

此处说明了此类多重定义的规则basic.def.odr/6 .列出的要求之一是“D 的每个定义都应包含相同的标记序列;”

修改该函数模板并重新编译一些使用 ODR 的翻译单元,并链接您的程序,而不重新编译所有使用它的翻译单元违反了 C++ 的单一定义规则.

诊断它不需要编译器工具链。

关于C++:当动态库中的内联函数发生变化时要重新编译什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46300862/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com