#Include Header Guard Format

#include header guard format?

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.

clang-format header include guard

As far as I know, clang-format doesn't currently support this.

However, you can do exactly this with clang-tidy (documented here). Invoke it like this:

clang-tidy -checks='-*,llvm-header-guard' -fix-errors myIncludeFile.h

Explanation:

  • The -* tells clang-tidy to disable all checks
  • The llvm-header-guard tells clang-tidy to enable the check which deals with include guards (documented here)
  • The -fix-errors tells clang-tidy to fix any resulting issues, even if it runs into other errors parsing the file

The llvm-header-guard expected format of the include-guards is exactly what you requested above; for example the file mydir/myfile.h would use MYDIR_MYFILE_H. I don't see any documentation which actually specifies that this is the format it uses, but I've verified at least version 6.0.0 does use that format.

Also see: clang include fixer, which does something similar.

C language, proper usage of include guards

Include guards are used to prevent double definition in case an include file get included more than once.

The standard include files have the necessary include guards, so you need no include guards for them.

Your code should be:

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

how to include header files more clearly in C++

You should be using include guards in Base.h.

An example:

// Base.h
#ifndef BASE_H
#define BASE_H

// Base.h contents...

#endif // BASE_H

This will prevent multiple-inclusion of Base.h, and you can use both OtherBase headers. The OtherBase headers could also use include guards.

The constants themselves can also be useful for the conditional compilation of code based on the availability of the API defined in a certain header.

Alternative: #pragma once

Note that #pragma once can be used to accomplish the same thing, without some of the problems associated with user-created #define constants, e.g. name-collisions, and the minor annoyances of occasionally typing #ifdef instead of #ifndef, or neglecting to close the condition.

#pragma once is usually available but include guards are always available. In fact you'll often see code of the form:

// Base.h
#pragma once

#ifndef BASE_H
#define BASE_H

// Base.h contents...

#endif // BASE_H

C++ Header Guard issues

Basically what your doing is #include "A.h" in framework.h and #include "framework.h" in A.h. This causes cyclic dependency of the header files and you will get errors such as undefined class A. To solve this, use forward declarations in header file and #include only in corresponding cpp file. If that is not possible then I don't see any other option other than including individual header files.

What is proper LLVM header guard style?

Looking at the unit tests:

  • https://github.com/llvm-mirror/clang-tools-extra/blob/master/unittests/clang-tidy/LLVMModuleTest.cpp

it seems to accept a few variations on the commonly used patterns. For a file named include/llvm/ADT/foo.h the convention seems to be:

#ifndef LLVM_ADT_FOO_H
#define LLVM_ADT_FOO_H
//...
#endif // LLVM_ADT_FOO_H

Template classes and include guards in C++

Templates definitions are supposed to be parsed once (and things like two phases name lookup are here so that as much errors as possible can be given immediately without having an instantiation). Instantiations are done using the internal data structure built at that time.

Templates definitions are usually (i.e. if you aren't using export or doing something special) in header files which should have their include guard. Adding one for template definition is useless but not harmful.

Is there a way to implement a header guard that doesn't have to be modified when the header file is renamed?

As others have noted, what you use as a header guard isn't intrinsically important; it just needs to be unique across the set of headers that might ever be co-included.

You can create a UUID or GUID and use that as the header guard (or a hash of some sort — MD5, SHA1, SHA2, SHA3, …). The only trick is dealing with the possibility of a leading digit; that's easily worked around (I used H_ as a prefix).

Mostly though, I use a name based on the file name, and don't usually rename headers often enough that it is a problem.

Here's a script called hdrguard that I use for generating the header guard lines for a given header file:

#!/bin/sh
#
# @(#)$Id: hdrguard.sh,v 1.8 2016/05/09 18:41:57 jleffler Exp $
#
# Generate #ifndef sequence to guard header against multiple inclusion

arg0=$(basename $0 .sh)

usestr="Usage: $arg0 [-bdfhimV] header.h [...]"

usage()
{
echo "$usestr" 1>&2
exit 1
}

help()
{
echo "$usestr"
echo
echo " -b Use base name of file for guard"
echo " -d Use _DOT_H after name (instead of _H)"
echo " -f Use specified path name of file for guard (default)"
echo " -h Print this help message and exit"
echo " -i Omit _INCLUDED after name"
echo " -m Generate MD5 hash value as header guard"
echo " -V Print version information and exit"
exit 0
}

opt_incl=yes
opt_base=no
opt_dot=no
opt_md5=no
while getopts bdfhimV opt
do
case "$opt" in
(b) opt_base=yes;;
(d) opt_dot=yes;;
(f) opt_base=no;;
(h) help;;
(i) opt_incl=no;;
(m) opt_md5=yes;;
(V) echo "$arg0: HDRGUARD Version "'$Revision: 1.8 $ ($Date: 2016/05/09 18:41:57 $)' | rcsmunger; exit 0;;
(*) usage;;
esac
done

shift $(($OPTIND - 1))

[ $# -eq 0 ] && usage

for i in "$@"
do
if [ $opt_base = yes ]
then i=$(basename $i)
fi
if [ $opt_dot = yes ]
then i=$(echo "$i" | sed 's/\.h$/_dot_h/')
fi
i=$(echo $i | tr 'a-z' 'A-Z' | tr -s '/+.-' '____' | sed 's/^_//')
if [ $opt_incl = yes ]
then
case "$i" in
(*_INCLUDED)
: OK;;
(*)
i="${i}_INCLUDED";;
esac
fi
if [ $opt_md5 = yes ]
then
tmp=$(mktemp ./hdrgrd.XXXXXXXX)
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
echo "$i.$(isodate compact)" > "$tmp"
i=$(md5 "$tmp" | sed 'y/abcdef/ABCDEF/; s/\([^ ]*\) .*/H_\1/')
rm -f "$tmp"
trap 0 1 2 3 13 15
fi
echo
echo "#ifndef $i"
echo "#define $i"
echo
echo "#endif /* $i */"
echo
done

It doesn't have code for SHA1, SHA2 or SHA3 — it optionally uses MD5 (in the form of a command md5). It would not be very hard to add support for alternative hashing algorithms. It doesn't require the file to exist.

Example uses:

$ hdrguard header.h

#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED

#endif /* HEADER_H_INCLUDED */

$ hdrguard -m header.h

#ifndef H_6DC5070597F88701EB6D2CCAACC73383
#define H_6DC5070597F88701EB6D2CCAACC73383

#endif /* H_6DC5070597F88701EB6D2CCAACC73383 */

$

I frequently use it from within vim, typing a command such as !!hdrguard % while the cursor is on an empty line to generate a header guard suitable for the header I'm editing. That's why it generates the blank lines top and bottom, too.

The command uses scripts isodate and rcsmunger. With the argument compact, the isodate command is equivalent to:

date +'%Y%m%d.%H%M%S'

The complete command supports a number of alternative formats and is more succinct than having to type the date command out everywhere. You're entirely at liberty to forego the use of a separate script and to just embed the expansion shown into hdrguard. Indeed, you could use just date and it would be OK; it is just seed material for the hashing operation to make the data being hashed unique.

$ isodate compact
20161228.185232
$

The rcsmunger command just converts RCS ID strings into a format I prefer for reporting version information:

#!/usr/bin/env perl -p
#
# @(#)$Id: rcsmunger.pl,v 1.9 2015/11/02 23:54:32 jleffler Exp $
#
# Remove the keywords around the values of RCS keywords

use strict;
use warnings;

# Beware of RCS hacking at RCS keywords!
# Convert date field to ISO 8601 (ISO 9075) notation
s%\$(Date:) (\d\d\d\d)/(\d\d)/(\d\d) (\d\d:\d\d:\d\d) \$%\$$1 $2-$3-$4 $5 \$%go;
# Remove keywords
s/\$([A-Z][a-z]+|RCSfile): ([^\$]+) \$/$2/go;

For example:

$ hdrguard -V
hdrguard: HDRGUARD Version 1.8 (2016-05-09 18:41:57)
$

You can regard the printing of version information as old-school version control; it has to be done differently if you use a DVCS such as git, which is one reason I've not done a wholesale migration to git for my personal software collection.

Naming Include Guards

From my own experience, the convention is to name the inclusion guards after the header file containing them with the exception that the name is all in caps and the period is replaced with an underscore.

So test.h becomes TEST_H.

Real life examples of this include Qt Creator, which follows this convention when auto-generating class header files.

Qt creator include guard pattern

I achieved to generate header guards of the form NAMESPACE_NESTEDNAMESPACE_CLASSNAME_H. I couldn't find anything to get the project name, but in my case it was not a problem as my top level namespace is my project name.

Following the answer of @Alan Birtles, I modified the cpp class wizard. You need to copy the files (file.cpp, file.h, wizard.json) from the QtCreator install directory to your home directory ($HOME/.config/QtProject/qtcreator/templates/wizards on Linux and macOS or %APPDATA%\QtProject\qtcreator\templates\wizards on Windows, according to the doc). Put them in the same subfolders (i.e. wizards/classes/cpp).

In wizard.json, change the line:

{ "key": "GUARD", "value": "%{JS: Cpp.headerGuard('%{HdrFileName}')}" },

to:

{ "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard('%{Class}', '%{JS: Util.suffix('%{HdrFileName}')}')}" },

Note that you can add some static text to your liking:

{ "key": "GUARD", "value": "RANDOM_TEXT_%{JS: Cpp.classToHeaderGuard('%{Class}', '%{JS: Util.suffix('%{HdrFileName}')}')}_INCLUDED" },

The complete files can be found here:
https://gist.github.com/juleswh/aeacc89342bc51b19044cf1e04483357

Hope this helps!


I used the following ressources, in case it might be usefull:

  • Documentation about qtcreator wizards: https://doc.qt.io/qtcreator/creator-project-wizards.html
  • Sources of some functions available from the wizard.json file:

    • https://github.com/qt-creator/qt-creator/blob/master/src/plugins/coreplugin/corejsextensions.h
    • https://github.com/qt-creator/qt-creator/blob/master/src/plugins/cpptools/cpptoolsjsextension.cpp


Related Topics



Leave a reply



Submit