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

时间:2015-06-03 12:12:29

标签: c gcc language-lawyer c11 gets

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

然而,我编译了以下代码:

#include <stdio.h>

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

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

并且编译时不会出现任何错误或警告。类似地,

#include <stdio.h>

int gets;

int main (void)
{}

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

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

  

符合要求的实施可能有扩展(包括附加   库函数),只要它们不改变任何行为   严格遵守计划

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

GCC版本4.9.1。

编辑:

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

3 个答案:

答案 0 :(得分: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);
   ^

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

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

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

答案 1 :(得分:1)

代码的关键行是:

#include <stdio.h>

您是否更新了系统的C库和标题?它们也是C实现的一部分,还有编译器。

答案 2 :(得分:1)

更新这可能不是问题的答案,我尝试将其设为信息。

我碰巧发现gcc提到获取不符合某些库问题glibc 2.16的C11标准。

请参阅gcc支持C11的状态:https://gcc.gnu.org/wiki/C11Status croped from the above link

但我找不到“库问题”的定义和其他版本的glibc的当前状态。

所以我在我的机器ubuntu16.04上试用了gcc版本5.3.1 20160413,glibc版本Ubuntu GLIBC 2.23 我们可以在编译时获得足够的警告,但是仍然可以执行“向后兼容性”的输出对象文件。

warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]
warning: the `gets' function is dangerous and should not be used.