C ABI:正在改变一个void函数来返回int一个突破性的变化?

Kor*_*nel 12 c return-type abi

是否有任何非奇特的架构/ OS /编译器的变化:

void func(void *, int, int)
Run Code Online (Sandbox Code Playgroud)

至:

int func(void *, int, int)
Run Code Online (Sandbox Code Playgroud)

打破ABI?(即,使用"int"版本运行时,为"void"版本的共享库编译的程序会中断)

Eri*_*hil 9

有几条评论说没有,我们可以通过一点推理加强这一点.在最熟悉的ABI中,void func(void *, int, int)允许带声明的函数使用寄存器,其中int结果将作为临时寄存器返回; 它不需要保存和恢复它.与声明的功能int func(void *, int, int)需要使用其中一个寄存器int结果将被返回.在其他方面,这些声明是相同的.因此,任何实现的int func(void *, int, int)机器代码也是满足的机器代码void func(void *, int, int).

换句话说,调用者无法区分故意在返回寄存器中返回结果的机器代码,该代码恰好在该寄存器中留下了一些临时计算.

注意,这种推理要求被调用的函数隐藏在ABI后面; 它依赖于ABI指定的二进制行为.如果在编译被调用函数时(或者可能影响调用实现方式的实现的其他部分)可以看到被调用函数的源,那么优化可能导致绕过ABI的行为(例如,观察被调用的例程)不使用返回寄存器,因此在调用者中使用它来保持一些预期在调用期间保持不变的值).

由于您说这是针对共享库的,因此您可能很安全:共享库是单独编译的,其源不可用于其调用者.但是,您应该考虑辅助渠道.例如,共享库可能是共享源并包含跨库调用的一组库的一部分.在这种情况下,某人可能有一个旧版本的共享库,该库是使用void源视图和包含int源的共享库的新版本编译的.(甚至这需要不寻常的源代码安排或花哨的编译器,它们将信息集成到多个编译单元中.)