
I've worked with the MSVC, Sun and GCC compilers. Each one of them supports #pragma once. Is there any reason to wrap this pragma within #ifdefs? Are there any compilers out there today that don't support this #pragma? #if defined( _MSC_VER ) && ( _MSC_VER >= 1020 ) # pragma once #endif Could we change this coding pattern so that it no longer looks like MSVC is being selfish? -Sid Sacek

Each one of them supports #pragma once. Is there any reason to wrap this pragma within #ifdefs? Are there any compilers out there today that don't support this #pragma?
Could we change this coding pattern so that it no longer looks like MSVC is being selfish?
[Edouard A.] In addition #pragma once may be faster than #ifndef/#endif because the compiler is not even going to open the file a second time to parse the #ifndef/#endif. ICC does support #pragma once as well. http://software.intel.com/en-us/articles/cdiag1782/ -- EA

Edouard A. wrote:
Each one of them supports #pragma once. Is there any reason to wrap this pragma within #ifdefs? Are there any compilers out there today that don't support this #pragma?
Could we change this coding pattern so that it no longer looks like MSVC is being selfish?
[Edouard A.]
In addition #pragma once may be faster than #ifndef/#endif because the compiler is not even going to open the file a second time to parse the #ifndef/#endif.
I've seen benchmarks that say some compilers (gcc, msvc) are smart enough to recognize #ifndef/#endif and do the #pragma once equivalent. (i.e. there's no discernable performance difference.) Can't find the link now though.. :( Cheers, /Marcus

I've seen benchmarks that say some compilers (gcc, msvc) are smart enough to recognize #ifndef/#endif and do the #pragma once equivalent. (i.e. there's no discernable performance difference.)
Nod. Can't comment on msvc but gcc supports the #ifndef...#endif idiom and doesn't reopen the file at all if it's already seen it. That said it wouldn't hurt to extend this to other compilers if we can sort out a definitive list. John.

Hi, On Fri, Apr 10, 2009 at 11:23 PM, Marcus Lindblom <macke@yar.nu> wrote:
I've seen benchmarks that say some compilers (gcc, msvc) are smart enough to recognize #ifndef/#endif and do the #pragma once equivalent. (i.e. there's no discernable performance difference.)
Sutter and Alexandrescu say the same in C++ Coding Standards Item #24, but with admonishment to keep all other code and comments in between to cater for less intelligent detection of include guards (whereas many header files in Boost have comments right at the top). Regards, Eugene Wee

Eugene Wee wrote:
Sutter and Alexandrescu say the same in C++ Coding Standards Item #24, but with admonishment to keep all other code and comments in between to cater for less intelligent detection of include guards (whereas many header files in Boost have comments right at the top).
Personally I'd be in favor of having the include guard starting right at the top, instead of starting with a few lines of comment. Although I don't know if doing so would significantly improve compilation times. Does it? Steven Watanabe wrote:
IMO, there is absolutely no reason to /rely/ on non-standard features even if /all/ compilers supported it in this case.
BTW, #pragma once has been discussed extensively at comp.std.c++, December 2007: "#pragma once in ISO standard yet?" http://groups.google.com/group/comp.std.c++/browse_thread/thread/c527240043c... Apparently it's hard to implement such a #pragma in a reliable way. There's also a related ticket: https://svn.boost.org/trac/boost/ticket/1532 HTH, Niels -- Niels Dekker http://www.xs4all.nl/~nd/dekkerware Scientific programmer at LKEB, Leiden University Medical Center

Niels Dekker - address until 2010-10-10 wrote:
BTW, #pragma once has been discussed extensively at comp.std.c++, December 2007: "#pragma once in ISO standard yet?" http://groups.google.com/group/comp.std.c++/browse_thread/thread/c527240043c...
Apparently it's hard to implement such a #pragma in a reliable way.
From what I understand, it's also hard to implement templates and multiple inheritance...or exception safety in code...but we have those =)

Raindog wrote:
Niels Dekker - address until 2010-10-10 wrote:
BTW, #pragma once has been discussed extensively at comp.std.c++, December 2007: "#pragma once in ISO standard yet?" http://groups.google.com/group/comp.std.c++/browse_thread/thread/c527240043c...
Apparently it's hard to implement such a #pragma in a reliable way.
From what I understand, it's also hard to implement templates and multiple inheritance...or exception safety in code...but we have those =)
The #pragma once depends on the compiler being able to correctly parse the include paths for all possibly attached file systems. If it fails, it might include the same file twice from seemingly different paths. With the #ifdef/#endif idiom, an occational extra include just adds a small amount of time to the compile. Bo Persson

Bo Persson wrote:
Raindog wrote:
Niels Dekker - address until 2010-10-10 wrote:
BTW, #pragma once has been discussed extensively at comp.std.c++, December 2007: "#pragma once in ISO standard yet?" http://groups.google.com/group/comp.std.c++/browse_thread/thread/c527240043c...
Apparently it's hard to implement such a #pragma in a reliable way.
From what I understand, it's also hard to implement templates and multiple inheritance...or exception safety in code...but we have those =)
The #pragma once depends on the compiler being able to correctly parse the include paths for all possibly attached file systems. If it fails, it might include the same file twice from seemingly different paths.
With the #ifdef/#endif idiom, an occational extra include just adds a small amount of time to the compile.
Bo Persson
Yet another example of the weakness of the C++ (lack of) project model...

10.04.2009, 23:26, "Marcus Lindblom" <macke@yar.nu>:
In addition #pragma once may be faster than #ifndef/#endif because the compiler is not even going to open the file a second time to parse the #ifndef/#endif.
I've seen benchmarks that say some compilers (gcc, msvc) are smart enough to recognize #ifndef/#endif and do the #pragma once equivalent. (i.e. there's no discernable performance difference.)
Can't find the link now though.. :(
It's in the docs of GCC, for example (even the ancient version 2.95.0 was optimized not to read same file twice if guards surround the whole file): http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8 Thanks, Maxim

On Sat, Nov 17, 2012 at 04:12:34AM +0800, Yanchenko Maxim wrote:
10.04.2009, 23:26, "Marcus Lindblom" <macke@yar.nu>:
In addition #pragma once may be faster than #ifndef/#endif because the compiler is not even going to open the file a second time to parse the #ifndef/#endif.
I've seen benchmarks that say some compilers (gcc, msvc) are smart enough to recognize #ifndef/#endif and do the #pragma once equivalent. (i.e. there's no discernable performance difference.)
Can't find the link now though.. :(
It's in the docs of GCC, for example (even the ancient version 2.95.0 was optimized not to read same file twice if guards surround the whole file): http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8
Beware that #pragma once is not supported on some of the toolchains that Boost pretends to target (SunStudio, etc.), and more importantly, has wildly diverging behaviour when it comes to symlinks and hardlinks, not to matter over network filesystems or multiple mounts of the same filesystem. It also runs into issues with duplicated headers, or replacement headers. Blindly trusting #pragma once in a cross-platform setting is very scary. Personally I only use it if I know very well the settings I'm deploying code myself in. -- Lars Viklund | zao@acc.umu.se

As additional data to this discussion, it have been pointed in an answer there : http://stackoverflow.com/questions/787533/is-pragma-once-a-safe-include-guar... That : "#pragma once does have one drawback (other than being non-standard) and that is if you have the same file in different locations (we have this because our build system copies files around) then the compiler will think these are different files." Which I don't know will help discuss this but might be relevant for such a big code base as boost libraries. Joel Lamotte

On Fri, Apr 10, 2009 at 4:26 PM, Sid Sacek <ssacek@securewatch24.com> wrote:
I've worked with the MSVC, Sun and GCC compilers.
Each one of them supports #pragma once. Is there any reason to wrap this pragma within #ifdefs? Are there any compilers out there today that don't support this #pragma?
I don't know if it's a supported compiler but IBM's vacpp compiler doesn't support it in version 7 although it does in version 9 (I have no version 8 to test with). Do we have a list of officially supported compilers ? Regards, Étienne

AMDG Etienne PIERRE wrote:
On Fri, Apr 10, 2009 at 4:26 PM, Sid Sacek <ssacek@securewatch24.com> wrote:
I've worked with the MSVC, Sun and GCC compilers.
Each one of them supports #pragma once. Is there any reason to wrap this pragma within #ifdefs? Are there any compilers out there today that don't support this #pragma?
I don't know if it's a supported compiler but IBM's vacpp compiler doesn't support it in version 7 although it does in version 9 (I have no version 8 to test with).
Do we have a list of officially supported compilers ?
IMO, there is absolutely no reason to /rely/ on non-standard features even if /all/ compilers supported it in this case. In Christ, Steven Watanabe

IMO, there is absolutely no reason to /rely/ on non-standard features even if /all/ compilers supported it in this case.
Cleaner code? Avoiding nasty copy/paste problems with include guard names? The fact that you can still automatically easily generate standards-compliant code for release tarballs? Anyway, I understand that a library like Boost doesn't want to rely on this, but personally, but it sounds sane to me that other projects (that are less depended on and don't need to support a gazillion of compilers) use it. cheers, Remko

I'm basically with everyone who's been saying to just not bother using "#pragma once" since the idiomatic ifdef guards work fine and unless there are some real benchmarks, I don't think it's worthwhile trying to bend over backwards to take advantage of something that's non-standard. I'm just not convinced there are any actual gains here. On Fri, Apr 10, 2009 at 11:33 AM, Remko Tronçon <remko@el-tramo.be> wrote:
Anyway, I understand that a library like Boost doesn't want to rely on this, but personally, but it sounds sane to me that other projects (that are less depended on and don't need to support a gazillion of compilers) use it.
Alright, I'll agree with this. While I'm not convinced it's a great idea for boost to use #pragma once, a library macro for users that uses it when available might make sense. Assuming _Pragma support, it's trivial to provide a macro BOOST_INCLUDE_ONCE that is defined as _Pragma( "once" ) in compilers that support it and nothing in compilers that don't (avoiding possible unrecognized pragma warnings). An alternative is a macro that produces a compile-time error if it's not supported. -- -Matt Calabrese

On Sat, Nov 17, 2012 at 4:33 AM, Matt Calabrese <rivorus@gmail.com> wrote:
I'm basically with everyone who's been saying to just not bother using "#pragma once" since the idiomatic ifdef guards work fine and unless there are some real benchmarks, I don't think it's worthwhile trying to bend over backwards to take advantage of something that's non-standard. I'm just not convinced there are any actual gains here.
On Fri, Apr 10, 2009 at 11:33 AM, Remko Tronçon <remko@el-tramo.be> wrote:
Anyway, I understand that a library like Boost doesn't want to rely on this, but personally, but it sounds sane to me that other projects (that are less depended on and don't need to support a gazillion of compilers) use it.
Alright, I'll agree with this. While I'm not convinced it's a great idea for boost to use #pragma once, a library macro for users that uses it when available might make sense. Assuming _Pragma support, it's trivial to provide a macro BOOST_INCLUDE_ONCE that is defined as _Pragma( "once" ) in compilers that support it and nothing in compilers that don't (avoiding possible unrecognized pragma warnings). An alternative is a macro that produces a compile-time error if it's not supported.
I would rather prefer BOOST_HAS_PRAGMA_ONCE macro in Boost.Config. Not all compilers support _Pragma (MSVC for one, and it's the primary target for the optimization), so I would still use #pragma guarded with the config macro. I know, in order to get BOOST_HAS_PRAGMA_ONCE defined I will have to include boost/config.hpp, but I do it anyway (so as most of Boost libraries, I presume). Disclaimer: I did not run performance tests to confirm the compile speed gains. But that #pragma once thing is almost a habit of mine, so it's not a big deal for me to add it to my headers.

#if defined( _MSC_VER ) && ( _MSC_VER >= 1020 ) # pragma once #endif
IMO, there is absolutely no reason to /rely/ on non-standard features even if /all/ compilers supported it in this case. Steven Watanabe
Just to make a small point; this is from the C++ standard... [quote] 16.6 Pragma directive [cpp.pragma] 1 A preprocessing directive of the form # pragma pp-tokensopt new-line causes the implementation to behave in an implementation-defined manner. The behavior might cause translation to fail or cause the translator or the resulting program to behave in a non-conforming manner. Any pragma that is not recognized by the implementation is ignored. [unquote] If unrecognized pragmas are ignored, then I don't see why boost developers should jump through a hoop to satisfy the "el-cheapo" compilers. In other words, if a compiler gives a warning about the #pragma-once, then let the programmer turn off the warning locally for the build, which is usually done in a single location within a makefile. On the other hand, every boost.hpp file has to surround the "#pragma once" with the silly looking guards. I tried this experiment just to see what happens. I added the non-existing #pragma to my code and got the following warning: #pragma once_upon_a_time foo.cpp(20) : warning C4068: unknown pragma My opinion is that the boost headers can happily contain the following code: #ifndef __HEADER_FILE_GUARD__ #define __HEADER_FILE_GUARD__ #pragma once ... #endif I have not yet heard about a compiler that doesn't support this #pragma. I would be surprised if a single developer calls up to complain about this. The compilers that warn against this #pragma can turn off the warnings with a single makefile change, like I mentioned before. Regards, -Sid Sacek

On Fri, Apr 10, 2009 at 3:34 PM, Sid Sacek <ssacek@securewatch24.com> wrote:
My opinion is that the boost headers can happily contain the following code:
#ifndef __HEADER_FILE_GUARD__ #define __HEADER_FILE_GUARD__ #pragma once ... #endif
Strictly speaking, if we don't count the #pragma which can do anything at all, the code above contains exactly one standard line (the one with the #endif) since __HEADER_FILE_GUARD__ is illegal identifier in user code. :) But that aside, what are you trying to achieve with #pragma once? Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

... the #pragma which can do anything at all... Emil Dotchevski
Really? Describe two things that #pragma-once can do? I can think of only one. ------------------------------------------------------------------------ ---------------- Look, large builds take major advantage of the capability of the #pragma-once statement. I added the #pragma-once to my company's builds and shaved off %26 from the build time. That's pretty significant within large builds. Along with precompiled headers, the #pragma- once feature is a very cool thing to have on your side. In fact, this feature is so cool that its capability was added to the #ifdef header guards in some compilers. But that to me is the wrong way to go because it makes the #ifdef non- standard. Remember that #define can be un-defined, and then what exactly does the header guard do in that case? #ifndef __BOOST_HEADER_GUARD__ #define __BOOST_HEADER_GUARD__ // this macro can be undefined #pragma once // the pragma-once cannot be turned off I'm not going to split hairs over what compilers do with their #define header-guards, but the point is that this cool feature is being used by loads of major C++ compilers. In every case the compiler treats the #pragma-once in exactly the same way. This is how standards come to be in future versions of products. shared_ptr<> was a boost thing and now it's a C++0x thing. The same thing appears to be happening with #pragma-once in an undocumented way because it's way too cool. I mean take a look at this ugly code below: #ifndef __BOOST_HEADER_GUARD__ #define __BOOST_HEADER_GUARD__ #if defined( _MSC_VER ) && ( _MSC_VER >= 1020 ) # pragma once #endif First off, it's just plain ugly. It's also error prone since it's got to be typed in exactly, but most important, it implies that no compiler other than Microsoft can take advantage of the #pragma-once capabilities of our modern day compilers. Boost libraries are constantly being cleaned up by deprecating stuff no longer needed, and this is one those things that needs to be deprecated, even though it's a very minor thing. I would be more than happy to perform the deprecation work. Regards, -Sid Sacek

On Fri, Apr 10, 2009 at 4:53 PM, Sid Sacek <ssacek@securewatch24.com> wrote:
... the #pragma which can do anything at all... Emil Dotchevski
Really? Describe two things that #pragma-once can do?
I can think of only one.
1. print a warning message 2. inhibit errors caused by misspelled or duplicate include guard Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
participants (17)
-
Andrey Semashev
-
Bo Persson
-
Edouard A.
-
Emil Dotchevski
-
Etienne PIERRE
-
Eugene Wee
-
John Maddock
-
Klaim - Joël Lamotte
-
Lars Viklund
-
Marcus Lindblom
-
Matt Calabrese
-
Niels Dekker - address until 2010-10-10
-
Raindog
-
Remko Tronçon
-
Sid Sacek
-
Steven Watanabe
-
Yanchenko Maxim