tags:

views:

223

answers:

7

if i have a several header files :lets say 1.h,2.h,3.h lets say the all the three header files have #include<stdlib.h> and one of the include files in them. when i have to use all 3 header files in a c file main.c it will have 3 copies #include<stdlib.h> after the preprocessor.how does the compiler handle this kind of conflict. is this an error or does this create any overhead?

EDIT:if there are no header guards what will happen?

+5  A: 

This is usually solved with preprocessor statements:

#ifndef __STDLIB_H
  #include <stdlib.h>
  #define __STDLIB_H
#endif

Although I never saw it for common header files like stdlib.h, so it might just be necessary for your own header files.

schnaader
Yes you are right! but if this is not implemented what would happen?how does the compiler handle?will it create any errors?
Vijay Sarathi
The include guards are always inside the .h file. if they weren't there you'd get lots of duplicate definition errors
John Burton
If someone else shipped a .h file without guards they are 1) incompetent or 2) doing something tricky and you would break it if you tried to "fix" it. (If #2, they are also possibly to clever for there own good.)
BCS
+5  A: 

The preprocessor will include all three copies, but header guards will prevent all but the first copy from being parsed.

Header guards will tell the preprocessor to convert subsequent copies of that header file to effectively nothing.

Response to edit:

Standard library headers will have the header guards. It would be very unusual and incorrect for them to not have the guards.

Similarly, it is your responsibility to use header guards on your own headers.

If header guards are missing, hypothetically, you will get a variety of errors relating to duplicate definitions.

Shmoopty
Where header guards are similar to schnaader's answer, but inside the stdlib.h header.
Richard Pennington
This is entirely correct, although I believe that many modern compilers recognise the header guards pattern the first time they include the file and know they don't need to open it again. That in no way changes how they work though it's just an optimization
John Burton
@JB, yes. I'm avoiding stating how many times the file is "opened". That's prone to misinterpretation, and really not relevant.
Shmoopty
"variety of errors" Heh.
Chad Okere
+2  A: 

This is done by one of the two popular techniques, both of which are under stdlib's responsibility.

One is defining a unique constant and checking for it, to #ifdef out all the contents of the file if it is already defined.

Another is microsoft-specific #pragma once, that has an advantage of not having to even read the from the hard drive if it was already included (by remembering the exact path)

You must also do the same in all header files you produce. Or, headers that include yours will have a problem.

Pavel Radzivilovsky
I belive that many compliers can recongise the include guard pattern and treat it in a similar way to the pragma. Although I've not verified myself that any specific compiler does this
John Burton
@JB: The CPP man page (gcc's pre-processor) says it does that.
BCS
+7  A: 

Most C headers include are wrapped as follows:

#ifndef FOO_H
#define FOO_H

/* Header contents here */

#endif

The first time the preprocessor scans this, it will include the contents of the header because FOO_H is undefined; however, it also defines FOO_H preventing the header contents from being added a second time.

There is a small performance impact of having a header included multiple times: the preprocessor has to go to disk and read the header each time. This can be mitigated by adding guards in your C file to include:

#ifndef FOO_H
#include <foo.h>
#endif

This stuff is discussed in great detail in Large-Scale C++ Software Design (an excellent book).

mrkj
BTW, gcc has a special case optimization in it's pre-processor to make the second form redundant.
BCS
Thanks; for anybody else wanting to follow up on this, the reference is here: http://gcc.gnu.org/onlinedocs/cpp/Once_002dOnly-Headers.html#Once_002dOnly-Headers
mrkj
+3  A: 

Another point: You can redeclare a function (or extern variable) a bazillion times and the compiler will accept it:

int printf(const char*, ...);
int printf(const char*, ...);

is perfectly legal and has a small compilation overhead but no runtime overhead.

That's what happens when an unguarded include file is included more than once.

Note that it is not true for everything in an include file. You can't redeclare an enum, for example.

Richard Pennington
+2  A: 

As far a I know regular include simply throws in the contents of another file. The standard library stdlib.h urely utilizes the code guards: http://en.wikipedia.org/wiki/Include%5Fguard, so you end up including only one copy. However, you can break it (do try it!) if you do: #include A, #undef A_GUARD, #include A again.

Now ... why do you include a .h inside another .h? This can be ok, at least in C++, but it is best avoided. You can use forward declarations for that: http://en.wikipedia.org/wiki/Forward%5Fdeclaration

Using those works for as long as your code does not need to know the size of an imported structure right in the header. You might want to turn some function arguments by value into the ones by reference / pointer to solve this issue.

Also, always utilize the include guards or #pragma once for your own header files!

Hamish Grubijan
I am not sure if including a header inside another is bad. What if a header needs stuff from another? I like my header files to be able to be `#include`d without the user remembering their correct order. Standard libraries behave the same way!
Alok
+1  A: 

As others have said, for standard library headers, the system must ensure that the effect of a header being included more than once is the same as the header being included once (they must be idempotent). An exception to that rule is assert.h, the effect of which can change depending upon whether NDEBUG is defined or not. To quote the C standard:

Standard headers may be included in any order; each may be included more than once in a given scope, with no effect different from being included only once, except that the effect of including <assert.h> depends on the definition of NDEBUG.

How this is done depends upon the compiler/library. A compiler system may know the names of all the standard headers, and thus not process them a second time (except assert.h as mentioned above). Or, a standard header may include compiler-specific magic (mostly #pragma statements), or "include guards".

But the effect of including any other header more than once need not be same, and then it is up to the header-writer to make sure there is no conflict.

For example, given a header:

int a;

including it twice will result in two definitions of a. This is a Bad Thing.

The easiest way to avoid conflict like this is to use include guards as defined above:

#ifndef H_HEADER_NAME_
#define H_HEADER_NAME_
/* header contents */
#endif

This works for all the compilers, and doesn't rely of compiler-specific #pragmas. (Even with the above, it is a bad idea to define variables in a header file.)

Of course, in your code, you should ensure that the macro name for include guard satisfies this:

  • It doesn't start with E followed by an uppercase character,
  • It doesn't start with PRI followed by a lowercase character or X,
  • It doesn't start with LC_ followed by an uppercase character,
  • It doesn't start with SIG/SIG_ followed by an uppercase character,

..etc. (That is why I prefer the form H_NAME_.)

As a perverse example, if you want your users guessing about certain buffer sizes, you can have a header like this (warning: don't do this, it's supposed to be a joke).

#ifndef SZ
#define SZ 1024
#else
#if SZ == 1024
#undef SZ
#define SZ 128
#else
#error "You can include me no more than two times!"
#endif
#endif
Alok