我看到了关于代码所使用的C的另一个问题gets()
,我评论了关于从不使用的常见警告,gets()
除非您想要演示如何破坏安全性.
这一次,我决定检查我的编译器是否发出了关于使用的警告gets()
.当然我希望它会.对,对吧?即使您没有指定任何警告?
想象一下,我的惊讶,当我发现,不仅编译器不会 默认警告,但我甚至不能弄清楚如何使之警告!
有问题的编译器是关于Debian的gcc 4.7.2,这是我使用的代码:
#includeint main(void) { char s[10]; gets(s); puts(s); return 0; }
尝试gcc g.c
.编译时没有警告.运行.如果输入太多文本,则获取段错误.
试过我通常放在makefile中的所有标准警告:
gcc -W -Wall -Wno-long-long -Wshadow -Wlarger-than-1000 \ -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align \ -Wconversion -Waggregate-return -Wmissing-prototypes \ -Wmissing-declarations -Wpadded -Wredundant-decls -Wnested-externs g.c
结果相同.
试过-std=c11
.考虑gets()
到C11中甚至不存在,即使这样也没有产生警告,这非常奇怪.也试过
c99
.没有警告.
那么这里发生了什么?当我在整个C语言中使用最弃用的函数时,为什么这个使用非常广泛的编译器不会警告我?
编辑:根据Keith Thompson的建议,我检查了一个弃用属性stdio.h
.它不存在.然后我复制了头文件并进行了实验.将这些字符串(我在其他标题中找到)添加到声明的末尾会产生警告:
__attribute_deprecated__ __attribute__ ((__deprecated__))
警告:
‘gets’ is deprecated (declared at /usr/include/stdiotz.h:632) [-Wdeprecated-declarations]
总结一下我到目前为止看到的响应,似乎我系统上的libc版本不包含警告,这在以后的版本中确实存在.这很奇怪,因为这个警告至少从1996年开始以某种形式存在.我模糊地回忆起libc已经至少分叉了一次,所以也许警告被遗漏在一个分支之外的时间明显晚于其他分支.
我想我会在Debian邮件列表上询问这个问题,并根据我学到的内容将其报告为bug.
编辑2:我看了一些源代码.自2007年以来,格里布至少已经发出了警告libio/iogets.c
.eglibc 2.13,我拥有的,具有完全相同的警告代码:
#ifdef _LIBC link_warning (gets, "the `gets' function is dangerous and should not be used.") #endif
我想_LIBC
在编译库时没有定义.为什么,我不知道.我不确定目的_LIBC
是什么.
所以,答案似乎归结为"它是图书馆,无论出于什么原因,在他们的智慧中,负责它的Debian开发者就这样编译了."我们可能永远不知道为什么.
不要把它报告为bug,因为我正在使用oldstable.如果在我下次升级后仍然如此,可能会提起它.
谢谢大家,感谢您的回复!
包含此警告消息的不是GCC,而是GLIBC.
您不太可能使用旧版本的GLIBC:至少自1996年以来警告已经出现.请参阅GitHub上此GLIBC代码的第67行作为示例(注意日期:1996年12月15日):
link_warning (gets, "the `gets' function is dangerous and should not be used.")
很可能你正在使用不同的C库.