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

Lun*_*din 12 c gcc gets language-lawyer c11

gets()功能已从C语言中删除.标准中不存在此类功能.

然而,我编译以下代码:

#include <stdio.h>

int main (void)
{
  (void) gets (NULL);
}
Run Code Online (Sandbox Code Playgroud)

运用

gcc -std=c11 -pedantic-errors -Wall -Wextra
Run Code Online (Sandbox Code Playgroud)

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

#include <stdio.h>

int gets;

int main (void)
{}
Run Code Online (Sandbox Code Playgroud)

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

在标准4.一致性§6中,我们可以阅读:

符合实现的实现可能具有扩展(包括附加库函数),前提是它们不会改变任何严格符合程序的行为

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

GCC版本4.9.1.

编辑:

gcc --version
gcc (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 4.9.1
Run Code Online (Sandbox Code Playgroud)

Kei*_*son 11

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);
   ^
Run Code Online (Sandbox Code Playgroud)

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

您正在使用仍提供该gets功能的库.因此,整个实现(由编译器gcc,库和其他一些部分组成)不符合C11.

结论:这不是一个gcc问题,gcc可以做的事情并不多.(好吧,它可以发出特殊情况诊断gets,但是它必须确定它不是对具有相同名称的用户定义函数的有效调用.)

  • @haccks:这个特定实现(MinGW)未能符合C11标准.(另请参阅MinGW的'long double`问题,适用于C90,C99和C11.)当然,我会说这是一个错误.(但它是一个容易避免的 - 不要使用`gets`,即使你的编译器没有警告你.) (3认同)
  • 将我的回复复制到您的其他评论:@haccks:是和否.在GNU C库提供的<stdio.h>头中,仍然声明了gets,但声明被#if!defined __USE_ISOC1 ... #endif包围.实现仍然存在,但是允许用户代码定义具有相同名称的函数. (2认同)