Reputation: 78748
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
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
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
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
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
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
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
Reputation: 14961
I prefer this format:
#ifndef FOO_HPP
#define FOO_HPP
/* ... */
#endif // FOO_HPP
MYLIB_FOO_HPP
, and it helps to avoid naming conflicts.Upvotes: 5
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
Reputation: 29882
To truly avoid name collisions, I use GUIDs:
#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED
Upvotes: 16
Reputation: 755357
If you are using Visual Studio or a Microsoft compiler use the pragma way
#pragma once
Upvotes: 3
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
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