当覆盖弱函数时,我该如何设置编译器警告(GNU GCC)?

6

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

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

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


这不是编译器警告,而是链接器警告。顺便说一下,GCC3.2是一个古老的编译器,不符合当前的C11和C++14标准。截至2016年3月,当前版本是GCC5,所以你应该升级你的gcc - Basile Starynkevitch
只要你定义符合标准(这可能有些棘手),就可以重新定义 fputc - Basile Starynkevitch
你为什么这样问?你想解决的实际问题是什么?看起来像是一个XY问题...所以请编辑你的问题,更详细地解释并说明动机。 - Basile Starynkevitch
我终于对这个问题进行了否定投票,因为它没有动力(我怀疑有些混淆)并且不是很清楚。 - Basile Starynkevitch
实际上,库函数被意外覆盖的可能性很小。首先,开发人员应该知道C标准库(不会意外地重用标准中定义的名称)。其次,即使他们重新定义了函数,也不太可能具有与标准所需的签名相同的签名。其他重新定义-具有良好签名的-不是意外,而是有目的的。 - Basile Starynkevitch
1个回答

3

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

库函数默认设置了弱属性(weak attribute)

这并不总是正确的;在我的系统上,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),而是链接器,更确切地说是动态链接器,即ld-linux(8)。警告只能在运行时可靠地给出(因为libc.so在构建时和运行时可能不同)。也许您需要LD_DYNAMIC_WEAK

如果您准备花费数周时间来解决问题,您可以考虑使用 GCC MELT 与自己的 MELT 扩展,并定制一个 recent GCC,以在可编译时可用的 libc 中重新定义弱符号时发出警告(这种检查的实用性有限,因为可能与运行时动态链接的 libc 不同)。
也许您可以使用一些 LD_PRELOAD trick
此外,如果您静态链接了应用程序,链接器可以给您提供诊断信息,如果您重定义了一个 libc 函数。
还要阅读 Drepper 的 How to Write a Shared Library 和 Levine 的 Linkers & loaders 书。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接