File included twice

C

Chris Dollin

Ravi said:
How can I prevent a header file from being included twice?

With a combination of #ifdef and #define.

The #define goes in the included file; the #defined symbol means
"the associated file has already been included".

[Do NOT NOT NOT start that symbol with a _, even though if you
look at your system header files you're likely to see them
doing that. /They/ are using leading _ because /they/ are
the implementation, keeping out of your way. Keep out of
theirs.]

The #ifdef can go in one of two places, each with its own
tradeoffs.

(a) It can go in the header file, so you get something like:

in spoo.h:

#ifndef H_SPOO
#define H_SPOO
... contents of spoo ...
#endif

(b) It can go around /each guarded #include/ of the header files:

in wantspoo.[ch]:

#ifndef H_SPOO
#include "spoo.h"
#endif

The (a) tactic makes each header self-contained: the conditional
machinery is buried inside it. You only have to get it right
once per file, not once per #include. Sequences of #includes
are nice and compact.

The (b) tactic avoids actually #including "lots" of text that
will then be ignored. If your header files are big big big, or
your file system slow slow slow, or the room available to your
compiler is small small small [1], that might reduce your
compilation overheads significantly.

Your call. [I choose (a) myself; I've not been in the situation
that would make (b) worth exploring. The mixed tactic of doing
some (a) and some (b) is an obvious invitation to trouble.]

[1] Which might be true, since not all C compilers run on
giga-{byte,hertz} processors with oodles of fast disc.
 
C

CBFalconer

Ravi said:
How can I prevent a header file from being included twice?

Well, one method is not to #include it twice. Another is to
install include guards, which could be something like (for foo.h
file):

#ifndef H_foo_h
# define H_foo_h
/* ... Normal content of foo.h */
#endif

In fact most of us routinely include such guards in each header.
 
T

Thad Smith

Chris said:
Ravi said:
How can I prevent a header file from being included twice?
....

The #ifdef can go in one of two places, each with its own
tradeoffs.

(a) It can go in the header file, so you get something like:

in spoo.h:

#ifndef H_SPOO
#define H_SPOO
... contents of spoo ...
#endif

(b) It can go around /each guarded #include/ of the header files:

in wantspoo.[ch]:

#ifndef H_SPOO
#include "spoo.h"
#endif

The (a) tactic makes each header self-contained: the conditional
machinery is buried inside it. You only have to get it right
once per file, not once per #include. Sequences of #includes
are nice and compact.

The (b) tactic avoids actually #including "lots" of text that
will then be ignored. If your header files are big big big, or
your file system slow slow slow, or the room available to your
compiler is small small small [1], that might reduce your
compilation overheads significantly.

Your call. [I choose (a) myself; I've not been in the situation
that would make (b) worth exploring. The mixed tactic of doing
some (a) and some (b) is an obvious invitation to trouble.]

I always use (a). If I want the speedup, I add the conditional in the
including code, but also leave it in the header. There is no reason to
have (b) only. No trouble is invited.
 
C

Chris Dollin

Thad said:
Chris said:
Ravi said:
How can I prevent a header file from being included twice?
...

The #ifdef can go in one of two places, each with its own
tradeoffs.

(a) It can go in the header file, so you get something like:

in spoo.h:

#ifndef H_SPOO
#define H_SPOO
... contents of spoo ...
#endif

(b) It can go around /each guarded #include/ of the header files:

in wantspoo.[ch]:

#ifndef H_SPOO
#include "spoo.h"
#endif

The (a) tactic makes each header self-contained: the conditional
machinery is buried inside it. You only have to get it right
once per file, not once per #include. Sequences of #includes
are nice and compact.

The (b) tactic avoids actually #including "lots" of text that
will then be ignored. If your header files are big big big, or
your file system slow slow slow, or the room available to your
compiler is small small small [1], that might reduce your
compilation overheads significantly.

Your call. [I choose (a) myself; I've not been in the situation
that would make (b) worth exploring. The mixed tactic of doing
some (a) and some (b) is an obvious invitation to trouble.]

I always use (a). If I want the speedup, I add the conditional in the
including code, but also leave it in the header. There is no reason to
have (b) only. No trouble is invited.

By "some (a) and some (b)" I meant [but failed] to imply that there
were some non-(a) and some non-(b), not (as in your case) all-(a)
with backstopping (b), a case that hadn't occurred to me.

Yours is safe. I presume you can now see why the case I had in mind
is inviting trouble.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top