Funny how these topics reappear so regularly.
#pragma once
was once very popular. It is still supported by every modern compiler.
Moreover, every modern compiler does it
even without the #pragma once directive.
The Problem
Pragma once / filename tracking can be defeated. This is not an abstract, if non-obvious problem.
The basic issue is that it is easily possible to produce multiple names for a single file. Or to duplicate a file’s content in another location.
Very large systems with hundreds of developers
do struggle with these issues.
The only solution that cannot be defeated
...remains using include guards — if done
correctly.
Because you can still screw up. The first is a rather obvious issue: you can choose a dumb name that conflicts with another library, like
STRING_H
. This isn’t so bad, except that it easily leads to the second problem:
Identical libraries with
different include guards.
Best practice
Always, always,
always use include guards. Make your include guards unique,
when you first create the file. Personally, I use something that cannot be confused:
1 2 3 4 5 6 7 8 9 10
|
#ifndef DUTHOMHAS_STRING_HELPERS_201903121140_HPP
#define DUTHOMHAS_STRING_HELPERS_201903121140_HPP
namespace duthomhas {
...
}
#endif
|
Yep. That’s the date I first created that include guard / library file, encoded right along with my unique name and file function.
This will never conflict with anyone else’s library (unless the conflict is intentional). No matter how the file / content / whatever is duplicated, the unique include guard gets carried right along with it.
The next point is also essential: when available, keep everything in a proper namespace.
Include guards protect against multiple identical symbols when compiling; namespaces protect against multiple identical symbols when
linking.
If, in addition, you wish to add the
#pragma once directive, there is no really good reason not to. (It might screw up the auto-detection of an extant compiler, but, as already mentioned, modern compilers can handle it with grace. Those that cannot will fall back to the include guard, as designed.)
So, don’t be surprised to find:
1 2 3
|
#include once
#ifndef MYFOO_SOMETHING_UNIQUE_HPP
#define MYFOO_SOMETHING_UNIQUE_HPP
|
Perfectly acceptable. Guaranteed not to break —
but only because of the unique include guard.
However, as the ISO committee recommends, using
#pragma once
is now more of a crutch than anything useful. I think it rightly recommends
discontinuing use. Again, all modern compilers already perform its function regardless of whether or not it is present.
Use unique include guards. Please don’t do it any other way.