库函数默认设置了弱属性(参见[1]),并且可能被意外的具有相同签名的函数“覆盖”。
例如printf
内部调用fputc
,我可以轻松声明我的一个函数int fputc(int, FILE *)
。
如果发生这种情况,我希望收到编译器警告。
有没有办法告诉编译器在覆盖弱函数的情况下警告我?
[1] https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html
答案 0 :(得分:3)
(我猜你是在Linux上,像往常一样编译和链接你的应用程序,特别是libc.so
动态链接)
库函数默认设置了弱属性
这并非总是如此;在我的系统fputc
上不是一个弱的符号:
% nm -D /lib/x86_64-linux-gnu/libc-2.21.so|grep fputc
000000000006fdf0 T fputc
0000000000071ea0 T fputc_unlocked
(如果它很弱,T
将是W
,而且write
确实很弱)
顺便说一下,重新定义自己的fputc
(或malloc
)是合法的(并且可能很有用,但非常棘手),前提是它保持语义符合标准。更普遍的弱符号预计可以重新定义(但这很棘手)。
有没有办法告诉编译器在覆盖弱函数的情况下警告我?
否(编译器无法警告您可靠)。
由于 只有可能会给你一些警告的东西而不是编译器(它不知道在运行时会使用哪个特定libc
,你可能会在编译后升级libc.so
但链接器,更确切地说是 dynamic linker ,即ld-linux(8)。并且警告只能在运行时可靠地给出(因为libc.so
在构建时和运行时可能不同)。也许你想要LD_DYNAMIC_WEAK
。
如果您已准备好花费数周时间处理解决方案,可以考虑将GCC MELT与您自己的 MELT 扩展程序一起使用,并自定义 recent {{3当编译时可用的libc
中的弱符号(在运行时可能不是libc
动态链接,因此这样的检查具有有限的用途)被重新定义时发出警告。
也许你可以使用一些GCC。
此外,如果您静态链接了应用程序,则链接器可以在重新定义libc
函数时为您提供诊断。
另请阅读Drepper的LD_PRELOAD
trick&莱文的How to Write a Shared Library书。