flo*_*t22 6 c gcc compiler-warnings
库函数默认设置了弱属性(参见[1]),并且可能被具有相同签名的函数"覆盖".例如printf内部调用fputc,我可以很容易地声明我的一个函数int fputc(int, FILE *).如果发生这种情况,我希望收到编译器警告.
有没有办法告诉编译器在覆盖弱函数的情况下警告我?
[1] https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html
(我猜你在 Linux 上,并像往常一样编译和链接你的应用程序,特别是libc.so 动态链接的)
库函数默认设置有weak属性
这并非总是如此; 在我的系统上fputc不是一个弱符号:
% nm -D /lib/x86_64-linux-gnu/libc-2.21.so|grep fputc
000000000006fdf0 T fputc
0000000000071ea0 T fputc_unlocked
Run Code Online (Sandbox Code Playgroud)
(如果它很弱,则将T是 a W,并且确实write很弱)
顺便说一句,重新定义您自己的fputc(或malloc) 是合法的(并且可能有用,但非常棘手),只要它保持符合标准的语义即可。更普遍的是,弱符号预计可以重新定义(但这很棘手)。
有没有办法告诉编译器在覆盖弱函数时发出警告?
否(编译器无法可靠地警告您)。
因为唯一可以给你一些警告的不是编译器(它不知道libc在运行时会使用哪个特定的,你可能会在libc.so编译后升级你的),而是链接器,更准确地说是动态链接器,即ld-linux (8) . 并且警告只能在运行时可靠地发出(因为libc.so在构建时和运行时可能会有所不同)。也许你想要LD_DYNAMIC_WEAK。
如果您准备花费数周的时间来研究解决方案,您可以考虑将GCC MELT与您自己的MELT扩展一起使用,并自定义最近的 GCC ,以便在编译时可用的弱符号(动态libc可能不相同)时发出警告libc在运行时链接,因此此类检查的用处有限)被重新定义。
也许你可以使用一些LD_PRELOAD技巧。
此外,如果您静态链接应用程序,则重新定义函数时链接器可以为您提供诊断信息libc。
另请阅读 Drepper 的《如何编写共享库》和 Levine 的《链接器和加载器》一书。