3

C++ has namespaces to prevent collisions of things with the same name.

Header guards serve a different purpose. They prevent includeing the same header twice. However, they can suffer from the same problem: what if two header guards from different files use the same popular name? What if there are two libraries that have a LinkedList class:

#ifndef LinkedList_H
#define LinkedList_H

// stuff

#endif

Why are those two means to uniquely identify code so different? It's like one sophisticated language feature on one side and some macro contraption with an arbitrary string on the other. Why are naming conflicts not a problem for header guards? Shouldn't the namespace be part of the header guard, to make it as unique as the namespace, so that it not only prevents duplicated include but also naming conflicts?

  • 1
    That's part of the reason many compilers support #pragma once. – Cubic Sep 13 '16 at 21:34
2

One method I use is to build a more complex macro name that has a practically zero chance of colliding with other names. This could be built from the following components:

  • Project name
  • Namespace name
  • File name
  • Random number or GUID

Example:

#if !defined MYPROJECT_MYNAMESPACE_FOO_HPP_9E72F091C4A833D7
#define ...

Overkill? Yes. Easy to do? Yes. Has such an infinitesimally small chance of a collision that I can write and forget about it? Yes.

  • Then why not derive it from the used namespace? Is that because you do not necessarily use only a single namespace per file which could make creating the macro name tricky? Or because in order to know the namespace, the compilation process has to start, which happens after preprocessor "applies" the header guards, which in turn would make some kind of double compilation necessary? Good old C++ feels somewhat clumsy in this regard compared to how C# or java handle the inclusion of other files. – null Sep 13 '16 at 22:07
  • @null I forgot that part - I do that when I use namespaces, which I generally do even when writing a regular program as opposed to a library. – user22815 Sep 13 '16 at 23:01
3

Header guards are not as sophisticated as namespaces because they are part of the preprocessor (like headers themselves), and the preprocessor is an extremely primitive part of C++, inherited from C.

A common convention is to add a project and in-project path as a prefix, e.g.

#ifndef MYPROJECT_UTILITY_CONTAINERS_LINKED_LIST_HPP
#define MYPROJECT_UTILITY_CONTAINERS_LINKED_LIST_HPP

It's not the only one of course.

3
#pragma once

Really, it supported by all major compillers (preprocessors). Some projects moves to use it: Qt Creator for example. Yes, it is non-standard.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.