我看到了又一篇关于使用C语言的问题,其中代码中使用了
这一次,我决定检查一下我的编译器是否会对使用
让我惊讶的是,我发现这个编译器不仅默认情况下没有发出警告,而且我甚至无法弄清如何让它发出警告!
这个问题的编译器是Debian上的gcc 4.7.2,以下是我使用的代码:
尝试使用命令“gcc g.c”进行编译,未出现警告。运行后,如果输入太多的文本,则会导致段错误。
我还尝试了在Makefile中添加所有标准警告信息:
警告:
总结目前所见的回答,我的系统上的libc版本不包含警告,而在后续版本中有。这很奇怪,因为该警告至少从1996年以来就存在了某种形式。我模糊地记得,libc至少已经被分叉了一次,因此可能警告被留在一个分支中的时间比其他分支要晚得多。
我想我会在Debian邮件列表上询问这个问题,并根据我所学到的情况可能会报告它作为一个错误。
编辑2:我已经查看了一些源代码。glibc自2007年起至少在libio/iogets.c中有警告。我使用的eglibc 2.13正好有相同的警告代码:
gets()
函数,我发表评论并警告说除了演示如何破解安全外,千万不要使用gets()
函数。这一次,我决定检查一下我的编译器是否会对使用
gets()
函数发出警告。当然,我认为应该会发出警告,是吧?即使你没有指定任何警告?让我惊讶的是,我发现这个编译器不仅默认情况下没有发出警告,而且我甚至无法弄清如何让它发出警告!
这个问题的编译器是Debian上的gcc 4.7.2,以下是我使用的代码:
#include <stdio.h>
int 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
。即使这也没有产生警告,这是相当奇怪的,因为在C11中gets()
甚至不存在。也尝试了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邮件列表上询问这个问题,并根据我所学到的情况可能会报告它作为一个错误。
编辑2:我已经查看了一些源代码。glibc自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开发者以那种方式进行了编译。”我们可能永远不会知道原因。
我不打算将其报告为错误,因为我正在使用旧版本。如果在我的下一次升级后仍然保持这种状态,我可能会提出来。
感谢大家提供有用的回复!
gcc -Wall -Wextra -g -std=c11
; жӮЁеҸҜиғҪиҝҳйңҖиҰҒеҚҮзә§жӮЁзҡ„libc
пјҢиҝҷе®һйҷ…дёҠж„Ҹе‘ізқҖе°ҶLinuxеҸ‘иЎҢзүҲжӣҙж–°еҲ°иҫғж–°зҡ„зүҲжң¬гҖӮ - Basile Starynkevitchgets
函数发出警告,如上所述。 - David C. Rankin/usr/include/stdio.h
在其对gets
的声明中具有__attribute_deprecated__
。你的/usr/include/stdio.h
是否也有这个? - Keith Thompson