考虑以下测试程序
#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;虽然这种行为似乎不仅仅是一个警告。是否有任何意义不停止编译?并且有没有人有任何建议如何阻止这导致相当大的文件的主要问题?
答案 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?