Rob
Rob

Reputation: 78748

#include header guard format?

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.

Upvotes: 20

Views: 14664

Answers (13)

nonsensation
nonsensation

Reputation: 3727

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.

Upvotes: 0

Fionn
Fionn

Reputation: 11285

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.

Upvotes: 20

Sebastian Mach
Sebastian Mach

Reputation: 39109

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

Upvotes: 0

Steve Jessop
Steve Jessop

Reputation: 279385

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.

Upvotes: 1

Evan Teran
Evan Teran

Reputation: 90523

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_

Upvotes: 0

Rob Wells
Rob Wells

Reputation: 37159

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

Upvotes: 1

efotinis
efotinis

Reputation: 14961

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.

Upvotes: 5

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507273

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)

Upvotes: 10

Scott
Scott

Reputation: 11206

I always use use

#ifndef FOOBAR_CPP

Upvotes: 1

Martin Cote
Martin Cote

Reputation: 29882

To truly avoid name collisions, I use GUIDs:

#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED

Upvotes: 16

JaredPar
JaredPar

Reputation: 755357

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

#pragma once

Upvotes: 3

James Curran
James Curran

Reputation: 103565

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.

Upvotes: 3

Zebra North
Zebra North

Reputation: 11492

I always use INCLUDED_FOO_HPP

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

Upvotes: 14

Related Questions