简体   繁体   English

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

[英]Not including stdlib.h does not produce any compiler error!

Hopefully this is a very simple question. 希望这是一个非常简单的问题。 Following is the C pgm (test.c) I have. 以下是我的C pgm(test.c)。

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

int main (int argc, char *argv[]) {
    int intValue = atoi("1");
    double doubleValue = atof("2");
    fprintf(stdout,"The intValue is %d and the doubleValue is %g\n", intValue, doubleValue);
    return 0;
}

Note that I am using atoi() and atof() from stdlib.h, but I do not include that header file. 请注意,我正在使用stdlib.h中的atoi()和atof(),但我没有包含该头文件。 I compile the pgm (gcc test.c) and get no compiler error! 我编译pgm(gcc test.c)并且没有编译错误!

I run the pgm (./a.out) and here is the output, which is wrong. 我运行pgm(./a.out),这是输出,这是错误的。

The intValue is 1 and the doubleValue is 0

Now I include stdlib.h (by removing the comments before the #include) and recompile it and run it again. 现在我包含stdlib.h(通过删除#include之前的注释)并重新编译它并再次运行它。 This time I get the right output: 这次我得到了正确的输出:

The intValue is 1 and the doubleValue is 2

How come the compiler did not complain about not including the stdlib.h and still let me use the atoi(), atof() functions? 为什么编译器没有抱怨不包含stdlib.h并且仍然让我使用atoi(),atof()函数?

My gcc info: 我的gcc信息:

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

Any thoughts appreciated! 任何想法赞赏!

For historical reasons -- specifically, compatibility with very old C programs (pre-C89) -- using a function without having declared it first only provokes a warning from GCC, not an error. 由于历史原因 - 特别是与非常旧的C程序(C89之前版本)的兼容性 - 使用未首先声明它的函数只会引发GCC的警告,而不是错误。 But the return type of such a function is assumed to be int , not double , which is why the program executes incorrectly. 但是这种函数的返回类型假定为int ,而不是double ,这就是程序执行错误的原因。

If you use -Wall on the command line, you get a diagnostic: 如果在命令行上使用-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’

You should use -Wall basically always. 你应该总是使用-Wall Other very useful warning options for new code are -Wextra , -Wstrict-prototypes , -Wmissing-prototypes , -pedantic , and -Wwrite-strings , but compared to -Wall they have much higher false positive rates. 新代码的其他非常有用的警告选项是-Wextra-Wstrict-prototypes-Wmissing-prototypes-pedantic-Wwrite-strings ,但与-Wall相比,它们具有更高的误报率。

Tangentially: never use atoi nor atof , they hide input errors. 切向:从不使用atoiatof ,它们隐藏输入错误。 Use strtol and strtod instead. 请改用strtolstrtod

If you don't specify otherwise, I believe a C compiler will just guess that undeclared functions take the form extern int foo() . 如果你没有另外指定,我相信C编译器只会猜测未声明的函数采用extern int foo()形式。 Which is why atoi works and atof doesn't. 这就是为什么atoi工作和atof没有。 Which compiler flags were you using? 你使用哪些编译器标志? I suggest using -Wall to turn on a bunch of gcc warnings, which should include referencing undeclared functions. 我建议使用-Wall打开一堆gcc警告,其中应包括引用未声明的函数。

C allows you to call a function without having a declaration for that function. C允许您在没有该函数声明的情况下调用函数。

The function will be assumed to return an int and arguments will be passed using default promotions. 假定该函数返回一个int并使用默认促销传递参数。 If those don't match what the function actually expects, you'll get undefined behavior. 如果那些与函数实际期望的不匹配,则会得到未定义的行为。

Compilers will often warn for this case, but not always (and that will also depend on compiler configuration). 编译器经常会警告这种情况,但并不总是(这也取决于编译器配置)。

In C, when you use a function that was not declared, it assumes that it has the default prototype: 在C中,当您使用未声明的函数时,它假定它具有默认原型:

int FUNCTION_NAME();

Note that in C using () as prototype means it accepts any arguments. 请注意,在C中使用()作为原型意味着它接受任何参数。

If you compile with the flag -Wall (I recommend you to always use this flag, since it enables all recommended warnings) you will get a warning (not an error) telling you that you are using an undeclared function. 如果使用标志-Wall进行编译(我建议您始终使用此标志,因为它启用了所有建议的警告),您将收到警告(而不是错误),告诉您正在使用未声明的函数。

C, unfortunately, does not require functions to be prototyped (or even declared) before use -- but without a prototype, it automatically makes certain assumptions about the function. 遗憾的是,C在使用之前不需要对函数进行原型化(甚至声明) - 但是如果没有原型,它会自动对函数做出某些假设。 One of those is that it returns an int. 其中之一是它返回一个int。 In your case, atoi does return an int , so it works correctly. 在你的情况下, atoi确实返回一个int ,所以它正常工作。 atof doesn't, so it doesn't work correctly. atof没有,所以它无法正常工作。 Lacking a prototype/declaration, you get undefined behavior -- typically it'll end up retrieving whatever value happens to be in the register where an int would normally be returned, and using that. 缺少原型/声明,你会得到未定义的行为 - 通常它最终将检索在通常返回int的寄存器中发生的任何值,并使用它。 It appears that in your particular case, that happens to be a zero, but it could just as easily be something else. 在您的特定情况下,似乎恰好是零,但它可能很容易成为其他东西。

This is one of the reasons many people push "C++ as a better C" -- C++ does require that all functions be declared before use, and further that you specify the types of all (non-variadic) parameters as well (ie a C++ function declaration is like a C prototype, not like a C declaration). 这是许多人将“C ++作为更好的C”推出的原因之一--C ++确实要求在使用之前声明所有函数,并且还要指定所有(非可变参数)参数的类型(即C ++)函数声明就像一个C原型,而不像C声明)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM