tags:

views:

1543

answers:

11

I know it makes little difference to a project but, assuming you use #defined header guards for your C++ code, what format do you use? e.g. assuming a header called foo.hpp:

#ifndef __FOO_HPP__
...

#ifndef INCLUDED_FOO_HPP
...

#ifndef SOME_OTHER_FORMAT

I'm sold on the idea of upper-case #defines but cannot settle on a format for these guards.

+9  A: 

I always use INCLUDED_FOO_HPP

I wouldn't use the double underscore one, because starting things with double underscores is reserved.

MrZebra
+1  A: 

I use

 #if !defined(FOO_HPP_INCLUDED)

I prefer the modern defined syntax because it allows || && operators, even if they aren't used here.

Also

 #ifndef __FOO_HPP__

is technically illegal, as leading underscores are reserved.

James Curran
Jonathan Leffler
+1  A: 

I always use use

#ifndef FOOBAR_CPP
Scott
+1  A: 

If you are using Visual Studio or a Microsoft compiler use the pragma way

#pragma once
JaredPar
And I was marked down becaues .... Completely valid and correct answer
JaredPar
Probably because this is not portable. Use the pragma, but put the include guards in as well, just in case you need to use a different compiler someday.
KeithB
because code like this would make you immediately fail an interview with me.
shoosh
check this out: http://learningcppisfun.blogspot.com/2008/02/pragma-once-standardized.html
DanJ
Even if you're using Visual Studio, you should still stick with the standard as far as possible.
jalf
@KeithB, question did not ask for portability.
JaredPar
@Shy, If you're failing people for correct answers with correct qualifications then you probably shouldn't be interviewing anyone.
JaredPar
This answer won't get an up-vote from me without a lot more qualifications and caveats in the text. I'm not sure about a down-vote; it is tempting, but not necessary.
Jonathan Leffler
Unless the question specifically asks for a platform specific solution, I always prefer a portable solution. Even if a platform is specified, given the choice between portable and platform-specific, a portable solution should be preferred.
KeithB
Also supported by GCC since 3.4, it's not just Microsoft. Of course the point about preferring portable code stands.
Steve Jessop
Note that Microsoft, in their own headers for VisualC++, which need Zero portability, use both style of guards.
James Curran
+7  A: 

To truly avoid name collisions, I use GUIDs:

#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED
Martin Cote
This makes sense in a weird way :-)
Leonardo Herrera
Use of date and time works too - if you dont want to generate GUIDs.
Jack
This works, but it will be confusing if you need to check for the header inclusion in some cpp file.
efotinis
+4  A: 

I prefer this format:

#ifndef FOO_HPP
#define FOO_HPP

/* ... */

#endif // FOO_HPP
  • A simple #ifndef instead of #if !defined(...), because it rarely makes sense to use a complex condition for a header guard.
  • The _HPP part to mark the identifier as a header guard.
  • No leading underscores, because such identifiers (starting with 2 underscores or with 1 underscore and capital letter) are reserved for the implementation.
  • The base part is just the file name, FOO. However, for library code that is going to be reused, it's advisable to add another part at the beginning. This is usually the containing namespace or the "module" name, e.g. MYLIB_FOO_HPP, and it helps to avoid naming conflicts.
efotinis
+8  A: 

Personally, i just use the filename FOO_HPP. Google uses the whole path like SRC_ENGINE_FAST_HPP.

Certain sets of names and function signatures are always reserved to the implementation:

  • Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.
  • Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

(17.4.3.1.2/1)

Johannes Schaub - litb
I second this, except that I prefer to use the same case on the #define as on the filename. In UNIX land (etc) FOO.HPP is not the same as foo.hpp.
divideandconquer.se
+14  A: 

I always included the namespace or relative path in the include guard, because only the header name alone has proven to be dangerous.

For Example you have some large project with the two files somewhere in your code

/myproject/module1/misc.h
/myproject/module2/misc.h

So if you use a consistent naming schema for your include guards you might end up with having _MISC_HPP__ defined in both files (very funny to find such errors).

So i settled with

MYPROJECT_MODULE1_MISC_H_
MYPROJECT_MODULE2_MISC_H_

These names are rater long but compared with the pain of double definitions it is worth it.

Another option, if you don't need compiler/platform independence you might look for some #pragma once stuff

Fionn
Thanks - I use lots of different modules/namespaces, so this makes sense. I'll lose the trailing underscore though. :)
Rob
+1  A: 

I've also always used something along the lines of:

#ifndef FOO_HPP
#define FOO_HPP 1

...

#endif

As most people have mentioned, don't prepend symbols with double underscores as that is reserved by the C++ standard for internal use by the implementation.

You might like to look at John Lakos's excellent book "Large Scale C++ Software Design" (Amazon link - sanitised for the script kiddy link nazis) for some considerations regarding header includes.

HTH

cheers,

Rob

Rob Wells
A: 

I tend to use:

#ifndef FILE_DATE_H_

(replace _H_ with the appropriate extension like _HPP_, etc). The date stamp is to avoid collisions with other same named headers in other directions/libraries.

so in the end it looks like this:

#ifndef SOMEFILE_20082411_H_
Evan Teran
+1  A: 

When I'm being paid for my time, and there isn't already a company standard, I use:

#ifndef path_to_file_h
#define path_to_file_h

The reason for the lowercase is that it's easier to copy and paste filenames and replace slashes with underscores. The reason for #ifndef is that it lines up nicely with #define, making it easier to see that the symbols are the same. I like the GUID idea, though, so I might try it out.

When I'm not being paid for my time, and not releasing my code into the wild, I just use #pragma once. Unlike most other portability issues, it's just as easy to add include guards later as now, and it can be done by someone who knows nothing about the code base (e.g. me in a year's time, or some innocent programmer I send my code to), so YAGNI applies.

Steve Jessop