隐式声明是否应该返回错误

时间:2014-01-02 13:29:52

标签: c gcc

考虑以下测试程序

#include<stdio.h>
#include<stdlib.h>
#include <math.h>

int main()
{
   double t = nan(NULL);
   printf("%g\n",t);
   return 0;
}

编译
/usr/local/bin/gcc  -lm -o test test.c

输出是预期的NaN。 但是,如果我输入错误或犯了错误并遗漏了

#include <math.h>

它编译正常,没有错误,没有警告,但输出为0

如果我使用-Wall进行编译,它会发出警告警告:隐式声明函数`nan&#39;虽然这种行为似乎不仅仅是一个警告。是否有任何意义不停止编译?并且有没有人有任何建议如何阻止这导致相当大的文件的主要问题?

2 个答案:

答案 0 :(得分:9)

  

隐式声明是否应返回错误

是。 C89中的隐含声明是“有效的”(但仍然存在问题,令人困惑和不良的做法),但在C99和C11中,它们是被禁止的。

C99,6.5.1.2:

  

标识符是主表达式,前提是它已被声明为指定对象(在这种情况下它是左值)或函数(在这种情况下它是函数指示符)。 79

     

79)因此,未声明的标识符违反了语法。

让你感到困惑的是GCC和clang(考虑到使用了命令行开关,我认为你正在使用其中之一)默认情况下不符合C实现,没有额外的严格标志,例如{ {1}}。

答案 1 :(得分:2)

The documentation of gcc在这个问题上非常明确:

  从GCC 4.5起基本上完全支持C99(-std = c99   使用了-pedantic-errors)[...]

实际上,如果您使用 -std=c99-pedantic-errors ,则会出现编译错误。


虽然我仍然想知道你是如何得到你写的结果的。我用gcc 4.7.2得到了一个非常不同的行为。您的代码提供了以下内容:

  

$ gcc -Wall -std = c99 -pedantic-errors bug.c -lm
  bug.c:在函数'main'中:
  bug.c:7:4:warning:null参数,其中非null需要(参数1)[-Wnonnull]

并且生成的可执行文件在我的计算机上发生了段错误。

但是,如果我将double t = nan(NULL);更改为double t = nan("");,则会进行编译。如果我注释掉#include <math.h>并省略-pedantic-errors标志,那么它甚至会编译并打印nan。两者都与你写的不同。您使用的是哪个版本的gcc?