繁体   English   中英

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

[英]C ABI: is changing a void function to return an int a breaking change?

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

void func(void *, int, int)

至:

int func(void *, int, int)

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

有几条评论说没有,我们可以通过一点推理加强这一点。 在最熟悉的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源的共享库的新版本编译的。 (甚至这需要不寻常的源代码安排或花哨的编译器,它们将信息集成到多个编译单元中。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM