为什么我可以在 gcc -std=c11 中使用 gets()?

Why can I use gets() in gcc -std=c11?

gets() 函数已从 C 语言中删除。标准中没有这样的功能。

然而我编译了以下代码:

#include <stdio.h>

int main (void)
{
  (void) gets (NULL);
}

使用

gcc -std=c11 -pedantic-errors -Wall -Wextra

它编译时没有给出任何错误或警告。同样,

#include <stdio.h>

int gets;

int main (void)
{}

不会编译(错误:'gets' 重新声明为不同类型的符号)。

在标准4. Conformance §6中我们可以读到:

A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program

鉴于上述情况,我认为 gcc 不符合标准,即使在迂腐模式下也是如此。是否有一个原因?这是故意的还是错误?

GCC 版本 4.9.1.

编辑:

gcc --version
gcc (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 4.9.1

您的代码的关键行是:

#include <stdio.h>

您是否更新了系统的 C 库和头文件?它们与编译器一起也是 C 实现的一部分。

更新这可能不是问题的答案,我尽量让它提供信息。

我碰巧发现 gcc 提到的 gets 没有遵循 C11 标准的一些库问题 glibc 2.16.

查看 C11 的 gcc 支持情况:https://gcc.gnu.org/wiki/C11Status

但是我找不到"library issue"的定义和其他版本glibc的当前状态。

所以我在我的机器 ubuntu16.04 上尝试了 gcc 版本 5.3.1 20160413、glibc 版本 Ubuntu GLIBC 2.23 我们可以在编译时得到足够的警告,但是执行 "Backwards compatibility".

的输出目标文件仍然可以
warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
warning: the `gets' function is dangerous and should not be used.

gcc 只是编译器,不是整个实现。

在我的系统上(Linux Mint 17.3、gcc 4.8.4、GNU libc 2.19),我得到:

$ gcc -std=c11 -pedantic-errors -Wall -Wextra -c c.c
c.c: In function ‘main’:
c.c:5:3: error: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
   (void) gets (NULL);
   ^

要正确诊断错误,实现 需要符合要求。这意味着编译器(首先从未提供 gets)和库。

您使用的库仍然提供 gets 功能。因此,实现作为一个整体(包括编译器 gcc、库和其他一些部分)不符合 C11。

底线:这不是 gcc 问题,gcc 对此无能为力。 (好吧,它 可以 gets 发出特例诊断,但随后它必须确定它不是对具有相同功能的用户定义函数的有效调用姓名。)