Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 不包括stdlib.h不会产生任何编译器错误!_C_Gcc_Std_Atof - Fatal编程技术网

C 不包括stdlib.h不会产生任何编译器错误!

C 不包括stdlib.h不会产生任何编译器错误!,c,gcc,std,atof,C,Gcc,Std,Atof,希望这是一个非常简单的问题。以下是我的C pgm(test.C) 现在我包括stdlib.h(通过删除#include之前的注释),然后重新编译并再次运行它。这次我得到了正确的输出: The intValue is 1 and the doubleValue is 2 为什么编译器没有抱怨没有包含stdlib.h,还让我使用atoi(),atof()函数 我的gcc信息: $ gcc --version gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27)

希望这是一个非常简单的问题。以下是我的C pgm(test.C)

现在我包括stdlib.h(通过删除#include之前的注释),然后重新编译并再次运行它。这次我得到了正确的输出:

The intValue is 1 and the doubleValue is 2
为什么编译器没有抱怨没有包含stdlib.h,还让我使用atoi(),atof()函数

我的gcc信息:

$ gcc --version
gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27)

任何想法都很感激

如果不另外指定,我相信C编译器只会猜测未声明的函数的形式是
extern int foo()
。这就是为什么
atoi
起作用而
atof
不起作用的原因。您使用了哪些编译器标志?我建议使用
-Wall
打开一组gcc警告,其中应包括引用未声明的函数。

C允许您调用函数,而无需声明该函数

该函数将被假定为返回一个
int
,参数将使用默认升级传递。如果这些与函数实际期望的不匹配,您将得到未定义的行为

编译器经常会在这种情况下发出警告,但并非总是如此(这也取决于编译器配置)。

由于历史原因——特别是与非常旧的C程序(C89之前)的兼容性——在没有先声明函数的情况下使用函数只会引发GCC的警告,而不是错误。但是这种函数的返回类型被假定为
int
,而不是
double
,这就是程序执行不正确的原因

如果在命令行上使用
-Wall
,则会得到一个诊断:

$ gcc -Wall test.c
test.c: In function ‘main’:
test.c:5: warning: implicit declaration of function ‘atoi’
test.c:6: warning: implicit declaration of function ‘atof’
你应该经常使用
-Wall
。新代码的其他非常有用的警告选项有
-Wextra
-Wstrict prototype
-Wmissing prototype
-pedantic
-Wwrite strings
,但与
-Wall
相比,它们的误报率要高得多


切向:切勿使用
atoi
atof
,它们会隐藏输入错误。改为使用
strtol
strtod

在C中,当您使用未声明的函数时,它假定它具有默认原型:

int FUNCTION_NAME();
注意,在C中,使用()作为原型意味着它接受任何参数


如果您使用flag-Wall进行编译(我建议您始终使用此标志,因为它启用了所有建议的警告),您将收到一条警告(不是错误),告诉您您正在使用未声明的函数。

C不幸的是,不要求函数在使用前进行原型化(甚至声明)——但没有原型,它会自动对函数进行某些假设。其中之一是它返回一个int。在您的例子中,
atoi
确实返回一个
int
,因此它工作正常
atof
无法正常工作,因此无法正常工作。由于缺少原型/声明,您会得到未定义的行为——通常,它会检索寄存器中通常会返回
int
的值,并使用该值。看起来在你的特殊情况下,它正好是零,但它也可能是其他的


这是许多人把“C++作为更好的C”的原因之一——C++要求在使用之前声明所有函数,并且还指定所有(非变量)参数的类型(即C++函数声明就像C原型,不像C声明)。(

-Wall
请!)C++没有指定哪个标准库标题可能包含哪些其他标题。C?(如果没有,我很可能包含
)C,不像C++,要求所有标准头都表现得好像它们不包含在一起。@ ZACK:谢谢你的澄清!我真的不知道。原则上<代码> - Werror < /C>是很好的,在实践中,当有人尝试在稍微不同的条件下编译和未初始化变量假阳性时,你的构建就会被炸毁。设置更改。<代码> >:(侧代码: WWSEDROUNT )默认为C++代码。C的代码大部分是默认的,因为大多数C代码仍然是C89(SHIVE),C89没有<代码> const 。C89确实有<代码> const ;它是“传统”C没有。但是C(即使在最新的草稿标准中,AFAIK)定义了字符串常量的类型,它是代码“Car *< /C> >,不像C++。<代码> -WWSED字符串将C与C++连接。我参与了编译GCC本身时打开的项目;它按一个工作年的顺序来清除少量错误。我不能真的责怪委员会。或者不考虑向后兼容性问题。即使在使用
atoi
的情况下,是否存在未定义的行为?@Giorgi:否。如果函数与编译器所做的假设相匹配,则没有问题。只有当存在不匹配(例如使用atof)时,才会出现未定义的行为。如果
atoi()
被传递一个
char*
之后,即使没有原型,它也不会是未定义的行为。
$ gcc -Wall test.c
test.c: In function ‘main’:
test.c:5: warning: implicit declaration of function ‘atoi’
test.c:6: warning: implicit declaration of function ‘atof’
int FUNCTION_NAME();