20

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.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Rob
  • 76,700
  • 56
  • 158
  • 197

13 Answers13

20

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 rather 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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Fionn
  • 10,975
  • 11
  • 54
  • 84
  • Thanks - I use lots of different modules/namespaces, so this makes sense. I'll lose the trailing underscore though. :) – Rob Nov 24 '08 at 21:05
15

To truly avoid name collisions, I use GUIDs:

#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED
Martin Cote
  • 28,864
  • 15
  • 75
  • 99
  • This makes sense in a weird way :-) – Leonardo Herrera Nov 24 '08 at 19:57
  • Use of date and time works too - if you dont want to generate GUIDs. – Jack Nov 25 '08 at 02:22
  • This works, but it will be confusing if you need to check for the header inclusion in some cpp file. – efotinis Nov 25 '08 at 09:08
  • 2
    Unlikely that my system will have as many include files as there are atoms in the known universe - unless we have subatomic hard drives. – new123456 Jul 11 '11 at 22:35
  • 1
    *To truly avoid name collisions* with GUIDs, forbid copying code ;) ... honestly: it may be harder to check if each unique header in a given code base has its own unique include guard using GUIDs compared to using human readable identifiers. Maybe there could be a hook running on each commit. – Wolf Nov 21 '17 at 10:23
14

I always use INCLUDED_FOO_HPP

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

Zebra North
  • 11,412
  • 7
  • 37
  • 49
  • As I learned, [double underscores are reserved not only at the beginning](https://stackoverflow.com/a/228797/2932052) – Wolf Nov 21 '17 at 10:14
10

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
  • 496,577
  • 130
  • 894
  • 1,212
  • 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. – activout.se Nov 24 '08 at 19:10
5

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
  • 14,565
  • 6
  • 31
  • 36
3

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
  • 101,701
  • 37
  • 181
  • 258
  • Not sure what this got a down-vote. It isn't wrong, even if I'd always use #ifndef instead of !defined() because there's no requirement to use || or && in this context. – Jonathan Leffler Nov 24 '08 at 19:28
3

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

#pragma once
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 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 Nov 24 '08 at 18:44
  • because code like this would make you immediately fail an interview with me. – shoosh Nov 24 '08 at 18:44
  • check this out: http://learningcppisfun.blogspot.com/2008/02/pragma-once-standardized.html – DanJ Nov 24 '08 at 18:45
  • Even if you're using Visual Studio, you should still stick with the standard as far as possible. – jalf Nov 24 '08 at 18:45
  • @KeithB, question did not ask for portability. – JaredPar Nov 24 '08 at 18:57
  • 5
    @Shy, If you're failing people for correct answers with correct qualifications then you probably shouldn't be interviewing anyone. – JaredPar Nov 24 '08 at 18:58
  • 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 Nov 24 '08 at 19:25
  • 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 Nov 24 '08 at 20:17
  • Also supported by GCC since 3.4, it's not just Microsoft. Of course the point about preferring portable code stands. – Steve Jessop Nov 25 '08 at 02:12
  • Note that Microsoft, in their own headers for VisualC++, which need Zero portability, use both style of guards. – James Curran Nov 25 '08 at 12:34
1

I always use use

#ifndef FOOBAR_CPP
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
Scott
  • 11,046
  • 10
  • 51
  • 83
1

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
  • 36,220
  • 13
  • 81
  • 146
1

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
  • 273,490
  • 39
  • 460
  • 699
0

I'd go with the filepath + the boost _INCLUDED suffix plus the nowadays widely supported #pragma once

In alot editors (for me its sublime) you can also define some macros/snippets for this.

Here is one that does it for you:

<snippet>
    <content><![CDATA[
#ifndef ${1:${TM_FILEPATH/(.*\/(include|src))*([^a-zA-Z0-9_]+)*([a-zA-Z0-9_]+)([.])*([a-zA-Z0-9_]+)*/\U$4_$6/ig}_INCLUDED}
#define $1
#pragma once


$0


#endif // $1
]]></content>
    <tabTrigger>incguard</tabTrigger>
    <description>include guard</description>
</snippet>

so yourproject/include/yourlib/yourfile.hpp

becomes YOURLIB_YOURFILE_HPP_INCLUDED

An additional external source code style checker tool could easily track consistency of your guards this way.

nonsensation
  • 3,627
  • 6
  • 28
  • 41
0

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
  • 87,561
  • 32
  • 179
  • 238
0

I use

<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>

or

<FILENAME_IN_ALL_CAPS>_INCLUDED_<YYYYMMDD>

Keeping it synchronous with folder hierarchies is too annoying (friend of refactoring), GUIDs are too annoying, the date suffix is good enough. If I would have to equally named files on the same day, I would

<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>a
<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>b
<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>...
Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130