如何在覆盖弱函数时设置编译器警告(GNU GCC)

时间:2016-03-04 07:40:37

标签: c gcc compiler-warnings

库函数默认设置了弱属性(参见[1]),并且可能被意外的具有相同签名的函数“覆盖”。 例如printf内部调用fputc,我可以轻松声明我的一个函数int fputc(int, FILE *)。 如果发生这种情况,我希望收到编译器警告。

有没有办法告诉编译器在覆盖弱函数的情况下警告我?

[1] https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html

1 个答案:

答案 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书。