tags:

views:

190

answers:

7

I know it to prevent multiple inclusion of header file. But suppose I ensure that I will include this file in only one .cpp file only once. Are there still scenarios in which I would require this safe-guard?

+11  A: 

No, that's the only purpose of the include guards, but using them should be a no-brainer: doing it requires little time and potentially saves a lot.

Paolo Tedesco
+1  A: 

That's its sole raison d'etre. It's still a good idea even if you think you have that covered; it doesn't slow your code down or anything, and it never hurts to have an extra guard.

Thom Smith
+1  A: 

The purpose of the guard is to prevent the file from being re included in the same .cpp file more than once. It does not protect against including the file in more than one .cpp file.

If you are sure that a header file isn't included in another header file, then the guard is not required. but it's still good form.

even better form is to use

#pragma once

if your compiler supports it.

John Knoeller
The include guard is better IMHO because it is more portable. I avoid reliance on compiler-specific features like the plague.
Chris Lutz
@Chris: portability matters for open source code. But usually not for closed source. #pragma once is more reliable and faster than guards because the compiler can actually _skip_ rescanning the file. That's the sort of thing that actually matters in a closed source shop.
John Knoeller
@John - GCC actually optimizes the include guard idiom to do essentially the same thing. But I agree that, for a closed-source codebase using Visual Studio, `#pragma once` is quite fine.
Chris Lutz
@Chris: I thought #pragma once was supported by GCC?
John Knoeller
@John - Apparently it is. I never use it so I didn't know, but a long time ago it was buggy and deprecated, but then they fixed it and un-deprecated it. Since GCC also optimizes include guards, I presume that it uses more or less the same code for both cases. (Another argument for the include guard is that you can test if you've already included a header in your code, but I doubt that would really be useful ever.)
Chris Lutz
+1  A: 

Ensuring your code is included only once is the sole purpose of a so-called "header guard".

This can be useful as if there's somewhere a circular dependency between your header files, you don't get caught in an endless loop of including files.

Sapph
+4  A: 

You can guarantee that your code only includes it once, but can you guarantee that anyone's code will include it once?

Furthermore, imagine this:

// a.h
typedef struct { int x; int y; } type1;

// b.h
#include "a.h"
typedef struct { type1 old; int z; } type2;

// main.c
#include "a.h"
#include "b.h"

Oh, no! Our main.c only included each once, but b.h includes a.h, so we got a.h twice, despite our best efforts.

Now imagine this hidden behind three or more layers of #includes and it's a minor internal-use-only header that gets included twice and it's a problem because one of the headers #undefed a macro that it defined but the second header #defined it again and broke some code and it takes a couple hours to figure out why there are conflicting definitions of things.

Chris Lutz
A: 

The additional scenario I can think of (and we did it) is to create C++ mocks.

You explicitly in your build define the file GUARD value and then you are able to add your own mock realization via -include my_mock.h as the additional compiler option (we used g++).

my_mock.h

#define THAT_FILE_GUARD

class ThatClass 
{
  void connect() 
  {
     std::cout << "mock connect" << std::endl;
  }
}
Mykola Golubyev
A: 

Using a header guard like this speeds up the compilation process, imagine having three source files using the header (minus the header guard), that in turn would mean the compiler would have to include the header (parsing and lexing the syntax) multiple times over.

With a header guard, the compiler will say 'Ha! I have seen this one before, and no I will not parse/lex the syntax' thereby speeding up the compilation process.

Hope this helps, Best regards, Tom.

tommieb75