Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is declaring an header file essential?

Tags:

c

Is declaring an header file essential? This code:

main()
{
  int i=100;

  printf("%d\n",i);
}

seems to work, the output that I get is 100. Even without using stdio.h header file. How is this possible?

like image 871
Manu Avatar asked Nov 29 '22 19:11

Manu


2 Answers

How is this possible? In short: three pieces of luck.

This is possible because some compilers will make assumptions about undeclared functions. Specifically, parameters are assumed to be int, and the return type also int. Since an int is often the same size as a char* (depending on the architecture), you can get away with passing ints and strings, as the correct size parameter will get pushed onto the stack.

In your example, since printf was not declared, it was assumed to take two int parameters, and you passed a char* and an int which is "compatible" in terms of the invocation. So the compiler shrugged and generated some code that should have been about right. (It really should have warned you about an undeclared function.)

So the first piece of luck was that the compiler's assumption was compatible with the real function.

Then at the linker stage, because printf is part of the C Standard Library, the compiler/linker will automatically include this in the link stage. Since the printf symbol was indeed in the C stdlib, the linker resolved the symbol and all was well. The linking was the second piece of luck, as a function anywhere other than the standard library will need its library linked in also.

Finally, at runtime we see your third piece of luck. The compiler made a blind assumption, the symbol happened to be linked in by default. But - at runtime you could have easily passed data in such a way as to crash your app. Fortunately the parameters matched up, and the right thing ended up occurring. This will certainly not always be the case, and I daresay the above would have probably failed on a 64-bit system.

So - to answer the original question, it really is essential to include header files, because if it works, it is only through blind luck!

like image 33
gavinb Avatar answered Dec 05 '22 02:12

gavinb


You don't have to include the header file. Its purpose is to let the compiler know all the information about stdio, but it's by no means necessary if your compiler is smart (or lazy).

You should include it because it's a good habit to get into - if you don't, then the compiler has no real way to know if you're breaking the rules, such as with:

int main (void) {
    puts (7);       // should be a string.
    return 0;
}

which compiles without issue but rightly dumps core when running. Changing it to:

#include <stdio.h>
int main (void) {
    puts (7);
    return 0;
}

will result in the compiler warning you with something like:

qq.c:3: warning: passing argument 1 of ‘puts’ makes pointer
                 from integer without a cast

A decent compiler may warn you about this, such as gcc knowing about what printf is supposed to look like, even without the header:

qq.c:7: warning: incompatible implicit declaration of
                 built-in function ‘printf’
like image 118
paxdiablo Avatar answered Dec 05 '22 01:12

paxdiablo