Reputation: 6378
What will happen if I don't include the header files when running a c program? I know that I get warnings, but the programs runs perfectly.
I know that the header files contain function declarations. Therefore when I don't include them, how does the compiler figure it out? Does it check all the header files?
Upvotes: 5
Views: 9539
Reputation: 726489
I know that I get warnings, but the programs runs perfectly.
That is an unfortunate legacy of pre-ANSI C: the language did not require function prototypes, so the standard C allows it to this day (usually, a warning can be produced to find functions called without a prototype).
When you call a function with no prototype, C compiler makes assumptions about the function being called:
int
...
vararg stuff)If the function being called with no prototype fits these assumptions, your program will run correctly; otherwise, it's undefined behavior.
Upvotes: 7
Reputation: 263217
Before the 1989 ANSI C standard, there was no way to declare a function and indicate the types of its parameters. You just had to be very careful to make each call consistent with the called function, with no warning from the compiler if you got it wrong (like passing an int
to sqrt()
). In the absence of a visible declaration, any function you call was assumed to return int
; this was the "implicit int" rule. A lot of standard functions do return int
, so you could often get away with omitting a #include
.
The 1989 ANSI C standard (which is also, essentially, the 1990 ISO C standard) introduced prototypes, but didn't make them mandatory (and they still aren't). So if you call
int c = getchar();
it would actually work, because getchar()
returns an int
.
The 1999 ISO C standard dropped the implicit int
rule, and made it illegal (actually a constraint violation) to call a function with no visible declaration. So if you call a standard function without the required #include
, a C99-conforming compiler must issue a diagnostic (which can be just a warning). Non-prototype function declarations (ones that don't specify the types of the arguments) are still legal, but they're considered obsolescent.
(The 2011 ISO C standard didn't change much in this particular area.)
But there's still plenty of code out there that was written for C90 compilers, and most modern compilers still support the older standard.
So if you call a standard function without the required #include
, what will probably happen is that (a) the compiler will warn you about the missing declaration, and (b) it will assume that the function returns int
and takes whatever number and type(s) of arguments you actually passed it (also accounting for type promotion, such as short
to int
and float
to double
). If the call is correct, and if you compiler is lenient, then your code will probably work -- but you'll have one more thing to worry about if it fails, perhaps for some unrelated reason.
Variadic functions like printf
are another matter. Even in C89/C90, calling printf
with no visible prototype had undefined behavior. A compiler can use an entirely different calling convention for variadic functions, so printf("hello")
and puts("hello")
might generate quite different code. But again, for compatibility with old code, most compilers use a compatible calling convention, so for example the first "hello world" program in K&R1 will probably still compile and run.
You can also write your own declarations for standard functions; the compiler doesn't care whether it sees a declaration in a standard header or in your own source file. But there's no point in doing so. Declarations have changed subtly from one version of the standard to the next, and the headers that came with your implementation should be the correct ones.
So what will actually happen if you call a standard function without the corresponding #include
?
In a typical working environment, it doesn't matter, because with any luck your program won't survive code review.
In principle, any compiler that conforms to C99 or later may reject your program with a fatal error message. (gcc will behave this way with -std=c99 -pedantic-errors
) In practice, most compilers will merely print a warning. The call will probably work if the function returns int
(or if you ignore the result) and if you get all the argument types correct. If the call is incorrect, the compiler may not be able to print good diagnostics. If the function doesn't return int
, the compiler will probably assume that it does, and you'll get garbage results, or even crash your program.
So you can study this answer of mine, follow up by reading the various versions of the C standard, find out exactly which edition of the standard your compiler conforms to, and determine the circumstances in which you can safely omit a #include
header -- with the risk that you'll mess something up next time you modify your program.
Or you can pay attention to your compiler's warnings (Which you've enabled with whatever command-line options are available), read the documentation for each function you call, add the required #include
s at the top of each source file, and not have to worry about any of this stuff.
Upvotes: 5
Reputation: 26164
For compatibility with old program C compilers can compile code calling functions which have not been declared, assuming the parameters and return value is of type int
. What can happen? See for example this question: Troubling converting string to long long in C I think it's a great illustration of the problems you can run into if you don't include necessary headers and so don't declare functions you use. What happened to the guy was he tried to use atoll
without including stdlib.h
where atoll
is declared:
char s[30] = { "115" };
long long t = atoll(s);
printf("Value is: %lld\n", t);
Surprisingly, this printed 0
, not 115
, as expected! Why? Because the compiler didn't see the declaration of atoll
and assumed it's return value is an int
, and so picked only part of the value left on stack by the function, in other words the return value got truncated.
That's why of the reasons it is recommended to compile your code with -Wall
(all warnings on).
Upvotes: 0
Reputation: 8053
First of all: just include them.
If you don't the compiler will use the default prototype for undeclared functions, which is:
int functionName(int argument);
So it will compile, and link if the functions are available. But you will have problems at runtime.
Upvotes: 1
Reputation: 12985
There are a lot of things you can't do if you leave out headers:
(I'm hoping to get some more from the comments since my memory is failing on this ...)
Upvotes: 0