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

How can I set a compiler warning (GNU GCC) when overwriting a weak function

库函数默认设置了 weak 属性(参见 [1]),可能 "overwritten" 具有相同签名的函数是偶然的。 例如 printf 内部调用 fputc,我可以很容易地声明我的函数之一 int fputc(int, FILE *)。 如果发生这种情况,我希望收到编译器警告。

有没有办法告诉编译器在覆盖弱函数时警告我?

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

(我猜你在 Linux,并像往常一样编译和链接你的应用程序,特别是 libc.so 动态链接)

Library functions have the weak attribute set by default

这并不总是正确的;在我的系统上 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)是 合法的 (可能有用,但非常棘手),只要它保持符合标准的语义。更普遍的弱符号预计是可重新定义的(但这很棘手)。

Is there a way to tell the compiler to warn me in case of overwriting a weak function?

编译器无法可靠地警告您)。

因为 只有 可以给你一些警告的是 而不是编译器(它不知道哪个特定的 libc 将在 运行 时使用,您可以在编译后升级 libc.so)但链接器,更准确地说 dynamic linker, that is ld-linux(8)。并且警告只能在 运行 时间可靠地给出(因为 libc.so 在构建时间和 运行 时间可能不同)。也许你想要 LD_DYNAMIC_WEAK.

如果您准备好花数周时间研究解决方案,您可以考虑使用 GCC MELT with your own MELT extension and customize a recent GCC 在编译时可用的 libc 中的弱符号时发出警告(这可能不是相同的 libc 在 运行 时动态链接,因此这种检查的用处有限)被重新定义。

也许你可以使用一些 LD_PRELOAD trick

此外,如果您静态链接您的应用程序,如果您重新定义 libc 函数,链接器可以为您提供诊断。

另请阅读 Drepper 的 How to Write a Shared Library & Levine's Linkers & loaders 书。