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

C 隐式声明是否应返回错误,c,gcc,C,Gcc,考虑以下测试程序 #include<stdio.h> #include<stdlib.h> #include <math.h> int main() { double t = nan(NULL); printf("%g\n",t); return 0; } 输出与预期一致。 但是,如果我打字错误或出错,并遗漏了 #include <math.h> #包括 它编译得很好,没有错误,没有警告,但给出0的输出 如果我使用-Wal

考虑以下测试程序

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

int main()
{
   double t = nan(NULL);
   printf("%g\n",t);
   return 0;
}
输出与预期一致。 但是,如果我打字错误或出错,并遗漏了

#include <math.h>
#包括
它编译得很好,没有错误,没有警告,但给出0的输出


如果我使用
-Wall
进行编译,它确实给出了警告:函数'nan'的隐式声明,尽管这种行为似乎不值得警告。不停止编译有什么意义吗?有没有人对如何阻止这种在较大的文件上引起严重头痛的情况有什么建议

隐式声明是否应返回错误

对。隐式声明在C89中是“有效的”(但仍然存在问题、混乱和不良做法),但在C99和C11中,它们是被禁止的

C99,6.5.1.2:

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

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

让您困惑的是,GCC和clang(鉴于使用的命令行开关,我认为您使用的是其中之一)在默认情况下不符合C实现,没有额外的严格标志,例如
-Werror-pedantic-pedantic errors

在这个主题上是非常清楚的:

从GCC 4.5开始,基本上完全支持C99(使用-std=C99 -使用迂腐的错误)[……]

事实上,如果同时使用
-std=c99
-pedantic errors
,就会出现编译错误


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

$gcc-Wall-std=c99-pedanticerrors-bug.c-lm
bug.c:在函数“main”中:
bug.c:7:4:警告:null参数,其中需要非null(参数1)[-Wnonnull]

生成的可执行文件在我的机器上因segfault崩溃


但是,如果我改变
double t=nan(NULL)
双t=nan(“”)然后编译。如果我注释掉
#include
并省略
-pedanticerrors
标志,那么它甚至编译并打印
nan
。两者都与你写的不同。您使用的是哪个版本的gcc?

请阅读编译器手册,了解如何使其为您提供正确的诊断。例如,您忘记了
-pedantic
。您真的不应该在没有-Wall的情况下运行GCC。“对于如何避免在较大的文件上造成严重问题,有人有什么建议吗?”-也使用
-Werror
。@kerrekSB-pedantic似乎对此没有任何区别
-std=gnu99-Wall-Werror-Wextra
-std=c99-Wall-Werror-Wextra
但c99允许隐式声明。@haccks不。你从哪里得到这个想法的?我多次在c99模式下编译这段代码:
main(){printf(“你好世界”);}
!(免责声明:不要打开您的
Werror
标志)。设置编译标志-std=c99仍然只会将其变成警告。@haccks为什么一直说“但是它编译了,但是它编译了,但是它编译了”?我不在乎。没人在乎。标准不在乎。它不应该编译。如果它可以编译,那么你的编译器就是垃圾(是的,我是说GCC是垃圾,而Clang是垃圾)。时期如果你不相信我,请阅读标准。去问一下标准委员会。我在早些时候对@H2CO3的评论中说的是,尽管C99禁止隐式声明,但代码将编译成
-std=C99-Wall-pedantic
(带有警告)。注意:我没有在这里使用
Werror
-pedantic errors
。但不应编译,因为标准禁止它。(在GCC-4.8.1上编译)。@haccks,如果传递正确的标志,则不会编译。您只需阅读文档中的第一句话,就可以了解强制执行C99需要哪些标志(
-std=C99
-pedantic errors
)。事实上,我没有C99草稿,只有C11。这里没有提到。@haccks我恐怕不明白。我指的是GCC的医生。@hacks我也是直到今天。:)我个人认为强制执行一个标准需要两个标志是令人困惑的。好吧,至少有文件证明。。。
#include <math.h>