I am currently working on a big project and maintaining all those include guards makes me crazy! Writing it by hand is frustrating waste of time. Although many editors can g
Include guards are definitely an annoyance, and C should have originally been designed such that headers would be included once by default - requiring some special option to include a header multiple times.
However, it wasn't ,and you're mostly stuck with having to use include guards. That said, #pragma once
is pretty widely supported so you might be able to get away with using it.
Personally, I solve your 1st problem (similarly named include files) by adding a GUID to the include guard. It's ugly, and most people hate it (so I'm often forced to not use it at work), but your experience shows that the idea has some value - even if it is hideously ugly (but then again the whole include guard thing is kind of a hack - why not go whole hog?):
#ifndef C_ASSERT_H_3803b949_b422_4377_8713_ce606f29d546
#define C_ASSERT_H_3803b949_b422_4377_8713_ce606f29d546
// blah blah blah...
#endif
I've heard that compilers don't actually reopen header files that have include guards (they've learned to recognize the idiom). I'm not sure if that's true (or to what extent it's true); I've never measured it. I also don't worry about it, but my projects aren't so huge that it's a problem.
My GUID hack pretty much solves items 1, 5, and 6. I just live with items 2, 3, and 4. Actually, for item 2 you could live without renaming the include guard macro when you rename the file as the GUID will ensure it remains unique. In fact, there's no reason to incorporate the filename at all with the GUID. But I do - tradition, I suppose.
You can probably avoid name collisions without resorting to random strings by setting the include guard to contain the name of the class and namespace that's in the file.
Besides, #pragma once is supported by both MS compilers and GCC for quite some time now so why does it bother you that it's not on the ISO standard?
A directive like #pragma once
is not trivial to define in a fully portable way that has clear an unambiguous benefits. Some of the concepts for which it raises questions are not well defined on all systems that support C
, and defining it in a simple way might provide no benefit over conventional include guards.
When the compile encounters #pragma once
, how should it identify this file so that it doesn't include its contents again?
The obvious answer is the unique location of the file on the system. This is fine if the system has unique locations for all files but many systems provide links (symlinks and hardlinks) that mean that a 'file' doesn't have a unique location. Should the file be re-included just because it was found via a different name? Probably not.
But now there is a problem, how is it possible to define the behaviour of #pragma once
in a way that has an exact meaning on all platforms - even those that don't even have directories, let alone symlinks - and still get the desirable behaviour on systems that do have them?
You could say that a files identity is determined by its contents, so if an included file has a #pragma once
and a file is included that has exactly the same contents, then the second and subsequent #include
s shall have no effect.
This is easy to define and has well defined semantics. It also has good properties such that if a project is moved from a system that supports and uses filesystem links to one that doesn't, it still behaves the same.
On the downside, every time an include file is encountered containing a #pragma once
its contents must be checked against every other file using #pragma once
that has already been included so far. This implies a performance hit similar to using #include
guards in any case and adds a not insignificant burden to compiler writers. Obviously, the results of this could be cached, but the same is true for conventional include guards.
Conventional include guards force the programmer to choose a macro that is the unique identifier for an include file, but at least the behaviour is well-defined and simple to implement.
Given the potential pitfalls and costs, and the fact the conventional include guards do work, it is not surprising to me that the standards committee didn't feel the need to standardize #pragma once
.