内联如何限制升级版本的二进制兼容性

How inlining could constrain binary compatibility for upgrade releases

本文关键字:版本 二进制 兼容性 何限制      更新时间:2023-10-16

我知道过度使用内联函数可能会影响二进制可升级性。当可升级性很重要时,必须避免这种情况。但是,我无法弄清楚内联如何影响二进制兼容性。拜托,有人可以说明一下。

在声明函数、变量和类型(也称为"符号")时,还应将它们声明为导出。不同的编译器以不同的方式实现这一点(Visual Studio使用__declspec(dllexport)(以及其他一些我懒得谷歌的方法),而GCC使用各种可见性开关。我相信clang使用GCC语义(或相对兼容),并且不熟悉其他编译器导出符号的方法。

如果你内联

你的函数并且它实际上是内联的(如果你把它声明为一个可导出的符号,我会认为这是一个编译器错误),那么你如何从你的库之外调用它?作为函数内联过程的一部分,编译器通常会删除或返工序言和尾声指令,因为它们不再需要(例如,不再需要在 x86 上retn - 只需将返回值存储在它将要使用的寄存器中)。

现在假设在库的一个早期版本上,您使用了一些声明为内联但实际上并未内联的函数(例如,递归函数)。其他人来了,开始使用你的图书馆。在更高版本中,您将重新设计代码以删除递归;突然间,编译器可以内联函数并选择内联,因此隐藏导出。现在,您的现有客户(无论谁在使用您的图书馆)都缺少符号。您破坏了二进制兼容性。