如何让 gcc 4.7 警告使用臭名昭著的 gets() 函数?

How to make gcc 4.7 warn about use of the infamous gets() function?

我看到另一个关于 C 的问题,其中代码使用 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。即使这样也没有产生警告,这是 很奇怪,考虑到 gets() 在 C11 中甚至不存在。尝试过 c99 也是。没有警告。

这是怎么回事?为什么这个使用非常广泛的编译器不警告 当我使用整个C语言中最不赞成使用的函数时的我?


编辑:根据下面 Keith Thompson 的建议,我检查了一个 stdio.h 中的弃用属性。它不在那里。然后我复制了 header 文件并进行了实验。添加这些字符串中的任何一个(我 在其他 headers) 中发现到声明的末尾确实生成了 警告:

__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 开发人员负责 那样编的。”我们可能永远不知道为什么。

不会将其报告为错误,因为我使用的是 oldstable。可能带来 如果在我下次升级后它仍然是这样的话,那就起来吧。

谢谢大家的翔实回复!

不是 GCC 包含此警告消息,而是 GLIBC。

您使用的 GLIBC 版本不太可能太旧:自 1996 年以来,警告一直在 至少 左右。请参阅 this GLIBC code 的第 67 行 GitHub 举个例子(注意日期:1996 年 12 月 15 日):

link_warning (gets, "the `gets' function is dangerous and should not be used.")

很可能您正在使用不同的 C 库。