Header guards are necessary in nearly all C++ programs, but are a pain when naming conventions are strictly enforced - especially so during refactoring. When using GCC (and many other compilers) we have an alternative in the preprocessor command #pragma once
. The recommendations I've seen against the use of this command (e.g. lack of support before v3.4) aren't very convincing with regard to my personal projects. I would like to use #pragma once
if possible.
All that said, this quote from the GCC website is giving me pause:
Note that in general we do not recommend the use of pragmas; See Function Attributes, for further explanation.
Maybe it's just my lower-journeyman-level C++ experience working against me, but I don't see any explanation for that recommendation at the site pointed to by that link. Is anyone able to explain the reasoning behind their recommendation in (semi-)layman's terms?
The general recommendation comes from the fact that not only is there no guarantee that other compilers implement #pragma once
(or any other pragma), there's no guarantee that other compilers implement #pragma once
the same way GCC does. Another compiler could legitimately give it an entirely different meaning, or worse, a subtly different one. If you don't care about your code being portable, you can ignore the recommendation.
Personally, I just use normal #ifndef
/#define
include guards in my own headers, even for my own personal projects. It's not really all that much typing, and is guaranteed to work everywhere. Naming conflicts with guard macros have never been an issue for me, and I try not to worry about problems I don't have.
I have once done survey of documentation of various C++ compilers and this is the result of the survey:
#if defined (_MSC_VER) \
|| (defined (__BORLANDC__) && __BORLANDC__ >= 0x0650) \
|| (defined (__COMO__) && __COMO_VERSION__ >= 400) /* ??? */ \
|| (defined (__DMC__) && __DMC__ >= 0x700) /* ??? */ \
|| (defined (__clang__) && __clang_major__ >= 3) \
|| (defined (__GNUC__) && (__GNUC__ >= 4 \
|| (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)))
# define LOG4CPLUS_HAVE_PRAGMA_ONCE
# pragma once
#endif
As you can see, the #pragma once
is supported by every major compiler out there. This is corroborated by Wikipedia page of #pragma once
.
So, to answer the original question, the problem with pragmas is that they are very compiler specific. That is way their use in general is discourage for portability reasons. OTOH, this particular pragma is supported across virtually all C++ compilers. Do not feel bad for using it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With