tags:

views:

116

answers:

3

I had only just noticed my programs using the string class were compiling without including the <string> header. It turns out that <iostream> includes <ios_base> which in turn includes <string>.

Is this bad practice and should I explicitly include <string>? Even if it's just a case of clarity?

Is it safe to assume this applies to more than just the <string> header? Perhaps this is implemenaton specific and or does the standard state thge <string> header be included via <ios_base> and <iostream>? Ensuring that any respected and widley used implementation will always include <string> providing the the call to <iostram> exists.

+5  A: 

You should explicitly include whatever standard library headers you need.

It is not specified which standard library headers are included by other standard library headers, so such details will differ between compilers.

One case where you can rely on a header being included by another header is if a class in one header derives from a class in another. For example, <iostream> has to include <ios_base> because classes defined in <iostream> are derived from classes defined in <ios_base>.

James McNellis
Whoever gets to port your application to a different operating system or update your app to build with a different compiler will thank you if you follow the advice of James McNellis in this matter. Believe me, I have had to write several scathing emails in the past week due to people not including the appropriate headers. Some other important ones: memset is not in memory.h, that's a non-standard Microsoftism. Another example: fabs and abs are in stdlib.h, not math.h.
George
Alf P. Steinbach
@Alf P. Steinbach: You're right about fabs, oops. abs is overloaded only for C++. Since we were compiling the same code with a C compiler instead of a C++ compiler, I had to go and replace a bunch abs() calls with fabs(). That's what I get for posting when I'm out of caffeine. :)
George
+6  A: 

A good practice is to always include the headers for the classes you'll be using in a given source file, regardless of whether you "know" they're included by already-included files.

If, while refactoring your code, you remove the necessity for one of the higher-level included files (iostream, for example), it could become quite painful to determine why your application no longer compiles.

TreDubZedd
+1 You litterally hit the submit button 2 seconds before my nearly word for word answer.
Shynthriir
+2  A: 

If you add a proper header (with '#pragma once' or the proper #ifndef) more than once, it only adds a little more time to compiling (just to open, parse and through away the header file contents), but nothing too serious while it makes your files more easy to compile, should the circumstances change (i.e. move them to a different project, make a library out of them, e.t.c.) If you are really concerned about compile time add the same #ifndef before including the header (though I don't recommend it)

i.e.

// header.h
#ifndef _HEADER_H
#define _HEADER_H
int blahblahblah(int);
#endif


// cppfile.cpp
#ifndef _HEADER_H
#include <header.h>
#endif
frag