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

元气小坏坏 提交于 2019-12-17 20:25:35

问题


Hopefully this is a very simple question. Following is the C pgm (test.c) I have.

#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. I compile the pgm (gcc test.c) and get no compiler error!

I run the pgm (./a.out) and here is the output, which is wrong.

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. 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?

My gcc info:

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

Any thoughts appreciated!


回答1:


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. But the return type of such a function is assumed to be int, not double, which is why the program executes incorrectly.

If you use -Wall on the command line, you get a diagnostic:

$ 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. 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.

Tangentially: never use atoi nor atof, they hide input errors. Use strtol and strtod instead.




回答2:


If you don't specify otherwise, I believe a C compiler will just guess that undeclared functions take the form extern int foo(). Which is why atoi works and atof doesn't. Which compiler flags were you using? I suggest using -Wall to turn on a bunch of gcc warnings, which should include referencing undeclared functions.




回答3:


C allows you to call a function without having a declaration for that function.

The function will be assumed to return an int and arguments will be passed using default promotions. 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).




回答4:


In C, when you use a function that was not declared, it assumes that it has the default prototype:

int FUNCTION_NAME();

Note that in C using () as prototype means it accepts any arguments.

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.




回答5:


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. One of those is that it returns an int. In your case, atoi does return an int, so it works correctly. atof doesn't, so it doesn't work correctly. 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. 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 (i.e. a C++ function declaration is like a C prototype, not like a C declaration).



来源:https://stackoverflow.com/questions/4800102/not-including-stdlib-h-does-not-produce-any-compiler-error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!