Where to include header files / A question of style?

V

Victor Bazarov

Exits Funnel said:
I'm a little confused about where I should include header files and was
wondering whether there was some convention. Imagine I've written a class
foo and put the definition in foo.h and the implementation of its member
functions in foo.cpp (which obviously #inludes foo.h) and further assume
that it depends on a class bar which is defined in bar.h.

It seems that there are the following two scenarios:

1) Both foo.h and foo.cpp depend on bar.h (eg, it's an argument to a
method).

2) Only foo.cpp depends on bar.h (eg, it's used in the implementation of
one of foo's methods.

So, for scenario (1), should I #include bar.h in only foo.h or should I
also #include it in foo.cpp?

I include it in both. The simple rule is this: never rely on indirect
inclusion, always be explicit. If 'foo.cpp' needs (uses) any classes or
symbols 'bar.h' defines, include 'bar.h' into 'foo.cpp'. Same with the
'foo.h'.
I realize that assuming proper header guards in bar.h it shouldn't matter
but I'm wondering if there is a convention and if so why?

There is no convention. When it comes to using a language that has
somewhat rigit (but limited) set of rules, the rules are the only thing
everybody follows (or supposed to, anyway).
What about scenario (2)? Should I #include bar.h in only foo.cpp, only in
foo.h or in both? Again, is there a convention and if so why?

Include it [only] where it's needed.

V
 
A

Alf P. Steinbach

* Victor Bazarov:
I include it in both. The simple rule is this: never rely on indirect
inclusion, always be explicit. If 'foo.cpp' needs (uses) any classes or
symbols 'bar.h' defines, include 'bar.h' into 'foo.cpp'. Same with the
'foo.h'.

In this case there's nothing implicit about it: [foo.h] is the header file
for [foo.cpp] and _defines_ the externally visible dependencies of [foo.cpp].
 
V

Victor Bazarov

Alf P. Steinbach said:
* Victor Bazarov:
I include it in both. The simple rule is this: never rely on indirect
inclusion, always be explicit. If 'foo.cpp' needs (uses) any classes or
symbols 'bar.h' defines, include 'bar.h' into 'foo.cpp'. Same with the
'foo.h'.

In this case there's nothing implicit about it: [foo.h] is the header file
for [foo.cpp] and _defines_ the externally visible dependencies of
[foo.cpp].

There are variations on the theme.

Imagine that you begin with
-------------------------------- foo.h
#include "bar.h"
class somefooclass { blah blah
somebarclass* pbar;
};
-------------------------------- foo.cpp
#include "foo.h" // let's rely on foo.h's including bar.h

... use pbar somehow
--------------------------------

Now, imagine that you looked at the compilation speed and decided
that you don't need 'bar.h' included in 'foo.h' and instead can
live with a forward (or even in-place) declaration:

------------------------------------ foo.h (version 2)
class somefooclass { blah blah
class somebarclass* pbar;
};
------------------------------------
Now your foo.cpp (and every other file that relied on the indirect
inclusion) is screwed and requires attention. If you did include
'bar.h' in those to begin with, there would be no need to change
the files, only to recompile them (since 'foo.h' header changed).

V
 
A

Alf P. Steinbach

* Victor Bazarov:
Now, imagine that you looked at the compilation speed and decided
that you don't need 'bar.h' included in 'foo.h' and instead can
live with a forward (or even in-place) declaration:

------------------------------------ foo.h (version 2)
class somefooclass { blah blah
class somebarclass* pbar;
};
------------------------------------
Now your foo.cpp (and every other file that relied on the indirect
inclusion) is screwed and requires attention. If you did include
'bar.h' in those to begin with, there would be no need to change
the files, only to recompile them (since 'foo.h' header changed).

That's a very good argument for being precise about versioning, e.g.
naming those two versions [foo_v1.h] and [foo_v2.h].

That fixes the "problem": the new version of foo is _not_ providing
the same interface as the old one, and going to the new version you
need to update all relevant files.

In one scenario there's just one relevant file, namely the wrapper
header for [foo] that all other files use, which is not controlled
by the developer of [foo].

Changing that wrapper header means also, test everything from the bottom up
(unit-test, assembly-test, system) again... :)

On the other hand, by allowing changes to the interface to [foo] to go
unnoticed one very likely to introduce bugs: well, it's just this simple
little change, that can't affect anything, I'll just replace [foo.h].
 
E

E. Robert Tisdale

Exits said:
I'm a little confused about where I should include header files
and was wondering whether there was some convention.
Imagine [that] I've written a class foo
and put the [class] definition in foo.h
and the implementation of its member functions in foo.cpp
(which obviously #inludes foo.h) and further assume that
[foo] depends on a class bar which is defined in bar.h.

It seems that there are the following two scenarios:

1) Both foo.h and foo.cpp depend on bar.h
(e.g., it's an argument to a method).

2) Only foo.cpp depends on bar.h
(e.g., it's used in the implementation of one of foo's methods.

So, for scenario (1), should I #include bar.h in only foo.h
or should I also #include it in foo.cpp?


Include header files *only* where they are needed.
In this case, it isn't necessary to include bar.h in foo.cpp explicitly.
I realize that assuming proper header guards in bar.h it shouldn't matter
but I'm wondering if there is a convention and if so why?

What about scenario (2)?
Should I #include bar.h in only foo.cpp, only in foo.h or in both?

Assuming that foo.h is a public interface
you should include bar.h *only* in foo.cpp
because you want to keep implementation details private.
Again, is there a convention and if so why?

A header file is just a file that is included near the top (head)
of a source file or another header file. They could contain anything
but the most common use is as a "public module interface" (foo.h).
The "private module implementation"
is sequestered in a source file (foo.cpp).
An interface has no "substance" which means that
it should not, by itself, cause the compiler to emit code
or reserve memory for data objects.
A header file which defines a module interface should be

1. idempotent -- it should have guard macros and
2. self sufficient -- it should include every header file
that it needs.
 
T

Thomas Matthews

Exits said:
Hello,

I'm a little confused about where I should include header files and was
wondering whether there was some convention. Imagine I've written a
class foo and put the definition in foo.h and the implementation of its
member functions in foo.cpp (which obviously #inludes foo.h) and further
assume that it depends on a class bar which is defined in bar.h.

It seems that there are the following two scenarios:

1) Both foo.h and foo.cpp depend on bar.h (eg, it's an argument to a
method).

2) Only foo.cpp depends on bar.h (eg, it's used in the implementation of
one of foo's methods.

So, for scenario (1), should I #include bar.h in only foo.h or should I
also #include it in foo.cpp? I realize that assuming proper header
guards in bar.h it shouldn't matter but I'm wondering if there is a
convention and if so why?

What about scenario (2)? Should I #include bar.h in only foo.cpp, only
in foo.h or in both? Again, is there a convention and if so why?

Thanks in advance for any replies. I realise this may be a silly
question but I'm pretty new to C++ and I'd like to follow any
established conventions whenever possible.

-exits

My style is:
1. If a forward declaration is all that is needed, then do so.
2. If you know the include guard mechanism, then use the preprocessor
to test that the header has already been included:
#ifndef BAR_H
#include "bar.h"
#endif
3. Otherwise just include the header file.

The above style is intended to speed up the compilation process by
not opening files unless necessary. If one just includes a header
without testing first, the compiler opens the file (time consuming),
tests the condition, searches for the "#endif" at the bottom of
the file (more wasted time), then closes the file (more time).

Just my opinion.


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
E

Exits Funnel

Hello,

I'm a little confused about where I should include header files and was
wondering whether there was some convention. Imagine I've written a
class foo and put the definition in foo.h and the implementation of its
member functions in foo.cpp (which obviously #inludes foo.h) and further
assume that it depends on a class bar which is defined in bar.h.

It seems that there are the following two scenarios:

1) Both foo.h and foo.cpp depend on bar.h (eg, it's an argument to a
method).

2) Only foo.cpp depends on bar.h (eg, it's used in the implementation of
one of foo's methods.

So, for scenario (1), should I #include bar.h in only foo.h or should I
also #include it in foo.cpp? I realize that assuming proper header
guards in bar.h it shouldn't matter but I'm wondering if there is a
convention and if so why?

What about scenario (2)? Should I #include bar.h in only foo.cpp, only
in foo.h or in both? Again, is there a convention and if so why?

Thanks in advance for any replies. I realise this may be a silly
question but I'm pretty new to C++ and I'd like to follow any
established conventions whenever possible.

-exits
 
E

E. Robert Tisdale

Thomas said:
My style is:
1. If a forward declaration is all that is needed, then do so.
2. If you know the include guard mechanism,
then use the preprocessor
to test [whether] the header has already been included:
#ifndef BAR_H
#include "bar.h"
#endif

No. Don't do this.
3. Otherwise just include the header file.

The above style is intended to speed up the compilation process
by not opening files unless necessary.
If one just includes a header without testing first,
the compiler opens the file (time consuming), tests the condition,
searches for the "#endif" at the bottom of the file (more wasted time),
then closes the file (more time).

This is *not* true.
The C preprocessor remembers the names of idempotent header files
and will not read them more than once in the same translation unit.
 
A

Alf P. Steinbach

* E. Robert Tisdale:
The C preprocessor remembers the names of idempotent header files
and will not read them more than once in the same translation unit.

Chapter & verse of the standard, please.
 
E

E. Robert Tisdale

Alf said:
E. Robert Tisdale:


Chapter & verse of the standard, please.
info cpp 'Once-Only Headers'
File: cpp.info, Node: Once-Only Headers, Next: Computed Includes,
Prev: Sear\ch Path, Up: Header Files


Once-Only Headers
=================


If a header file happens to be included twice, the compiler will process
its contents twice. This is very likely to cause an error, e.g. when
the compiler sees the same structure definition twice. Even if it does
not, it will certainly waste time.


The standard way to prevent this is to enclose the entire real
contents of the file in a conditional, like this:


/* File foo. */
#ifndef FILE_FOO_SEEN
#define FILE_FOO_SEEN


THE ENTIRE FILE


#endif /* !FILE_FOO_SEEN */


This construct is commonly known as a "wrapper #ifndef". When the
header is included again, the conditional will be false, because
`FILE_FOO_SEEN' is defined. The preprocessor will skip over the entire
contents of the file, and the compiler will not see it twice.


CPP optimizes even further. It remembers when a header file has a
wrapper `#ifndef'. If a subsequent `#include' specifies that header,
and the macro in the `#ifndef' is still defined, it does not bother to
rescan the file at all.


You can put comments outside the wrapper. They will not interfere
with this optimization.


The macro `FILE_FOO_SEEN' is called the "controlling macro" or
"guard macro". In a user header file, the macro name should not begin
with `_'. In a system header file, it should begin with `__' to avoid
conflicts with user programs. In any kind of header file, the macro
name should contain the name of the file and some additional text, to
avoid conflicts with other header files.
 
D

davidrubin

Victor said:
1) Both foo.h and foo.cpp depend on bar.h (eg, it's an argument to a
method). [snip]
So, for scenario (1), should I #include bar.h in only foo.h or should I
also #include it in foo.cpp?

I include it in both. The simple rule is this: never rely on indirect
inclusion, always be explicit. If 'foo.cpp' needs (uses) any classes or
symbols 'bar.h' defines, include 'bar.h' into 'foo.cpp'. Same with the
'foo.h'.

If the class 'Bar' (for example) is used in the *interface* of the
component 'foo', define it in foo.h, but *not* in foo.cpp. (However,
you must always include foo.h in foo.cpp.) This way you know that the
'foo' interface is correctly self-contained when you compile foo.cpp.
(I.e., you will get a compile-time error if you forget to include bar.h
in foo.h.)

In this case, you have a forward declaration of 'class Bar' in foo.h,
and your 'Foo' methods use references and/or pointers to 'Bar'. That
is, 'bar' is used in the *implementation* of 'foo'. You do not include
bar.h in foo.h, but you necessarily include bar.h in foo.cpp;
otherwise, foo.cpp will not compile.

/david
 
A

Alf P. Steinbach

* E. Robert Tisdale:
File: cpp.info, Node: Once-Only Headers, Next: Computed Includes,
Prev: Sear\ch Path, Up: Header Files

I meant chapter & verse of the standard; that's not the standard.
 
E

Exits Funnel

Thanks everyone for taking the time to reply. Judging by the range of
opinions it would seem that there is no solid convention :) Thanks again.

-exits
 
E

E. Robert Tisdale

Alf said:
* E. Robert Tisdale:


I meant chapter & verse of the standard; that's not the standard.

It is an optimization.
The standard does not specify any optimization.
This discussion is pointless, I suppose,
unless you can show where the standard forbids such optimizations.

External guard macros are superfluous at best
and can be a maintenance nightmare --
if you change the internal guard macros in a header file,
you must change the external guard macros
in every header and source file that includes that header file.
 
V

Victor Bazarov

Alf P. Steinbach said:
* E. Robert Tisdale:

I meant chapter & verse of the standard; that's not the standard.

Don't be like that, Alf. The thread started by a question about
a convention not about the Standard. If we were only concerned
with writing standard C++ programs, there would be no C++ books.
Do you read books? Why? You make it seem that all one needs to
know or learn is the Standard.
 
A

Alf P. Steinbach

* Victor Bazarov:
Don't be like that, Alf. The thread started by a question about
a convention not about the Standard. If we were only concerned
with writing standard C++ programs, there would be no C++ books.
Do you read books? Why? You make it seem that all one needs to
know or learn is the Standard.

OK. The point was just that one cannot rely on that optimization, it's
done differently by different compilers, and even by versions of the
same compiler (g++ is one example). I think good practice is to code in
a way such that the optimization is brought into play if the compiler
supports it, but at the same time so that the code will work anyway; and
of course, different programmers have different ideas about how to do that.

Cheers,

- Alf

PS: I must be doing something right because some people say I'm too concerned
with the standard, and some people say please confine your writings etc. to
the standard, ignore the UnHoly in-practice. :)
 
E

E. Robert Tisdale

Alf said:
Victor Bazarov:


OK. The point was just that one cannot rely on that optimization,
it's done differently by different compilers,
and even by versions of the same compiler (g++ is one example).
I think good practice is to code in a way such that
the optimization is brought into play if the compiler supports it
but at the same time so that the code will work anyway and, of course,
different programmers have different ideas about how to do that.

The external guard macros preclude this optimization.
The don't help. They just clutter up your code and name space
and frustrate the optimizer. You can't use them
with standard header files because they aren't portable
and you can't use them with third party library header files
because they may change with each new version of the library.
External guard macros are just another example
of premature optimization.

If your C preprocessor does not implement this optimization
the solution is to shop around for a better C preprocessor
and *not* to cobble your code to compensate for an inferior tool.
This optimization is supported by quality implementations
which are available for virtually every target platform.
 
A

Alf P. Steinbach

* E. Robert Tisdale:
The external guard macros preclude this optimization.

No, that's incorrect.

The don't help. They just clutter up your code and name space

That last is a good point.

and frustrate the optimizer.

No, that's incorrect.

You can't use them with standard header files because they aren't
portable
Right.


and you can't use them with third party library header files
because they may change with each new version of the library.

In general that's incorrect, but it depends much on the headers
in question.

External guard macros are just another example
of premature optimization.

That can be right, and it can be wrong, depending.

If your C preprocessor does not implement this optimization
the solution is to shop around for a better C preprocessor
and *not* to cobble your code to compensate for an inferior tool.
This optimization is supported by quality implementations
which are available for virtually every target platform.

The Lakos book is a bit old now, but that's one useful reference. In
other threads about this issue various people have tried out the
effect. External include guards, used via wrapper headers, have had a
distinct positive effect for header files residing on network drives.
In essence the compiler can employ the optimization for the wrapper
headers, so no difference for a compiler that employs this optimization.
A compiler that doesn't employ the optimization benefits both from
having local files and having very short files to scan.
 
R

Richard Herring

Victor Bazarov said:
Don't be like that, Alf. The thread started by a question about
a convention not about the Standard.

But then Tisdale made a specific pronouncement which is not in fact
generally true. Don't you think that deserves comment, lest he mislead
others?
 

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
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top