Proposal for #pragma once support

I would like to propose conditional support for #pragma once be added to all header files in boost. This would involve, at the beginning of every header file, a preprocessor check to determine whether or not the particular compiler is on a whitelist of known compilers to optimized #pragma once. If so, #pragma once is used. so, something like this: #if defined(_MSC_VER) /* || defined(OTHER_PRAGMA_ONCE_ENABLED_COMPILER) ... */ #pragma once #endif the rest of the header file, including the original #include guard, could be as normal. to demonstrate the motivation for this, consider the sample on this page: http://www.gamearchitect.net/Articles/ExperimentsWithIncludes.html. At the bottom there is a zip file with a visual studio solution that contains 3 different projects. Each project contains 200 header file, each of which includes all of the other 199 header files. There is a single cpp file with a main function which includes all 200 header files. All 3 projects use internal #include guards. In addition: Project 'RedundantGuard' - Uses external include guards (wrapping the invocation of #include itself inside the appropriate guard) as discussed in the book Large Scale C++ Software Design Project 'PragmaOnce' - Uses #pragma once Project 'Nothing' - Uses nothing additional other than the internal include guards. Here are the build timings on my machine (Visual Studio 2008 Service Pack 2) RedundantGuard - 1 second compile + link time PragmaOnce - 1 second compile + link time Nothing - 15 seconds compile + link time In addition I have tested this in the code base of a commercial product I am working on (~40,000 lines of code). It consists of about 6 different projects, some of which have dependencies between each other and some which don't, so that parallel compilation can happen in some instances RedundantGuard - Not Tested PragmaOnce - 1 minute, 25 seconds compile + link time Nothing - 2 minutes, 1 second compile + link time So, I believe that boost compile times can benefit significantly from this. Thoughts?

I brought this topic up a couple of months ago, and I got the "Boost Cold Shoulder". You see, I believe the head-honchos here are GCC aficionados and don't care much about Bill Gate's compilers. I hope you do better than I did. -Sid Sacek -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Zachary Turner Sent: Tuesday, June 09, 2009 12:00 PM To: boost@lists.boost.org Subject: [boost] Proposal for #pragma once support I would like to propose conditional support for #pragma once be added to all header files in boost. This would involve, at the beginning of every header file, a preprocessor check to determine whether or not the particular compiler is on a whitelist of known compilers to optimized #pragma once. If so, #pragma once is used. so, something like this: #if defined(_MSC_VER) /* || defined(OTHER_PRAGMA_ONCE_ENABLED_COMPILER) ... */ #pragma once #endif the rest of the header file, including the original #include guard, could be as normal. to demonstrate the motivation for this, consider the sample on this page: http://www.gamearchitect.net/Articles/ExperimentsWithIncludes.html. At the bottom there is a zip file with a visual studio solution that contains 3 different projects. Each project contains 200 header file, each of which includes all of the other 199 header files. There is a single cpp file with a main function which includes all 200 header files. All 3 projects use internal #include guards. In addition: Project 'RedundantGuard' - Uses external include guards (wrapping the invocation of #include itself inside the appropriate guard) as discussed in the book Large Scale C++ Software Design Project 'PragmaOnce' - Uses #pragma once Project 'Nothing' - Uses nothing additional other than the internal include guards. Here are the build timings on my machine (Visual Studio 2008 Service Pack 2) RedundantGuard - 1 second compile + link time PragmaOnce - 1 second compile + link time Nothing - 15 seconds compile + link time In addition I have tested this in the code base of a commercial product I am working on (~40,000 lines of code). It consists of about 6 different projects, some of which have dependencies between each other and some which don't, so that parallel compilation can happen in some instances RedundantGuard - Not Tested PragmaOnce - 1 minute, 25 seconds compile + link time Nothing - 2 minutes, 1 second compile + link time So, I believe that boost compile times can benefit significantly from this. Thoughts?

I brought this topic up a couple of months ago, and I got the "Boost Cold Shoulder".
You see, I believe the head-honchos here are GCC aficionados and don't care much about Bill Gate's compilers.
I hope you do better than I did.
-Sid Sacek
I'm not any sort of honcho here so I hope you don't mind if I disagree. Firstly, as an counter-example let me note there is currently a thread (not for the first time!) about getting gcc visibility support into Boost. It has historically had similar problems getting accepted that pragma once has. So the problems are not MS-specific thing. On the contrary, Boosters are generally highly pragmatic about supporting compiler suppliers whatever their software "philosophy". Rather, the Boost community has the structural bug-feature that each library owner is the "dictator" who says what goes in that library. This has some downsides: - changes across all libraries are hard (but not impossible) to achieve. On the one hand you need to convince a whole slew of active library authors that the change is wholly positive, but on the other hand no-one is going to do the changes (and any relevant documentation and testing) for you - so even seemingly small tasks are quite daunting and so even if the general groupthink is that something is a good idea doesn't mean it gets done! - I believe the same bug-feature is also at least partially responsible for the problems on trunk that David Abrahams and Robert Ramey have identified in another recent thread. Almost any library needs maintenance - new compilers and platforms come along with new quirks or improvements - more basic libraries may change underneath the library - bugs are found by users. Thus the single maintainer model has problems if the single maintainer no longer has time to devote to the task for whatever reason. What I am saying is that no-one is cold-shouldering you but rather there is no central authority figure who magically makes things happen. I doubt any of the above is controversial and I'm sure most Boosters would love to see these issues "fixed". But how to do so? No-one's being paid to be here! Pete

Pete Bartlett wrote:
I brought this topic up a couple of months ago, and I got the "Boost Cold Shoulder".
You see, I believe the head-honchos here are GCC aficionados and don't care much about Bill Gate's compilers.
I hope you do better than I did.
-Sid Sacek
I'm not any sort of honcho here so I hope you don't mind if I disagree.
I'm going to disagree, as well. I just went back into the archives and looked at your thread, and I'm confused by your perception of a cold shoulder. I count 26 posts in the thread over less than 4 days, in a discussion that includes some library maintainers and one of the moderators. This a reasonably active discussion for around here. I agree that no one showed up and said "You have permission, go ahead and do it." However, as Pete points out, that just isn't the way Boost works. All broad action in Boost happens by first building a wide consensus in the community. If you notice, when moderators such as Dave or Beman have ideas for changes, they follow the same process of discussion on the list and building consensus. On some occasions they don't generate enough interest or agreement and their ideas go by the wayside. It isn't always quick, but it is the way Boost works. More broadly, please continue contributing. Not every idea you have will be what the community does, but getting your ideas in the mix is central to how we function. (For the record, some of my ideas have gone down in flames, or just produced no broad interest, so I know where of I speak.) John

John and Pete, I do appreciate your insights into the inner workings of the Boost community. I'm not discouraged about the lack of interest in my suggestion, but I was somewhat surprised. Boost libraries are one of those things that make life better for programming engineers. I believed that was the unwritten philosophy behind Boost, to "Make Life Better." Extending that philosophical notion, the Boost libraries would also know about the shortcomings of compilers and operating systems and help to improve their performance as well, simply because it "makes life better." I suppose I must have been mistaken about that... perhaps not everybody in the Boost community has feelings of magnanimity and charity. -Sid Sacek -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of John Phillips Sent: Tuesday, June 09, 2009 6:15 PM To: boost@lists.boost.org Subject: Re: [boost] "boost cold shoulder" (was proposal for #pragma oncesupport) Pete Bartlett wrote:
I brought this topic up a couple of months ago, and I got the "Boost Cold Shoulder".
You see, I believe the head-honchos here are GCC aficionados and don't care much about Bill Gate's compilers.
I hope you do better than I did.
-Sid Sacek
I'm not any sort of honcho here so I hope you don't mind if I disagree.
I'm going to disagree, as well. I just went back into the archives and looked at your thread, and I'm confused by your perception of a cold shoulder. I count 26 posts in the thread over less than 4 days, in a discussion that includes some library maintainers and one of the moderators. This a reasonably active discussion for around here. I agree that no one showed up and said "You have permission, go ahead and do it." However, as Pete points out, that just isn't the way Boost works. All broad action in Boost happens by first building a wide consensus in the community. If you notice, when moderators such as Dave or Beman have ideas for changes, they follow the same process of discussion on the list and building consensus. On some occasions they don't generate enough interest or agreement and their ideas go by the wayside. It isn't always quick, but it is the way Boost works. More broadly, please continue contributing. Not every idea you have will be what the community does, but getting your ideas in the mix is central to how we function. (For the record, some of my ideas have gone down in flames, or just produced no broad interest, so I know where of I speak.) John _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 10 Jun 2009, at 16:39, Sid Sacek wrote:
John and Pete,
I do appreciate your insights into the inner workings of the Boost community. I'm not discouraged about the lack of interest in my suggestion, but I was somewhat surprised. Boost libraries are one of those things that make life better for programming engineers. I believed that was the unwritten philosophy behind Boost, to "Make Life Better." Extending that philosophical notion, the Boost libraries would also know about the shortcomings of compilers and operating systems and help to improve their performance as well, simply because it "makes life better."
I suppose I must have been mistaken about that... perhaps not everybody in the Boost community has feelings of magnanimity and charity.
The big problem I have is that there is no evidence that #pragma once would actually help in practice. It helps in some super-special case, involving 200 basically empty files that all include each other and nothing else. I suspect (without any evidence) that if someone came along and said "I added #pragma once to the boost headers, and it sped up compilation by X% on windows, and didn't slow things down on linux / mac os x, and it didn't break any test or library", they might well get a less luke-warm response. Chris

On Wed, Jun 10, 2009 at 10:44 AM, Christopher Jefferson < chris@bubblescope.net> wrote:
On 10 Jun 2009, at 16:39, Sid Sacek wrote:
John and Pete,
I do appreciate your insights into the inner workings of the Boost community. I'm not discouraged about the lack of interest in my suggestion, but I was somewhat surprised. Boost libraries are one of those things that make life better for programming engineers. I believed that was the unwritten philosophy behind Boost, to "Make Life Better." Extending that philosophical notion, the Boost libraries would also know about the shortcomings of compilers and operating systems and help to improve their performance as well, simply because it "makes life better."
I suppose I must have been mistaken about that... perhaps not everybody in the Boost community has feelings of magnanimity and charity.
The big problem I have is that there is no evidence that #pragma once would actually help in practice. It helps in some super-special case, involving 200 basically empty files that all include each other and nothing else. I suspect (without any evidence) that if someone came along and said "I added #pragma once to the boost headers, and it sped up compilation by X% on windows, and didn't slow things down on linux / mac os x, and it didn't break any test or library", they might well get a less luke-warm response.
Chris
FWIW I also mentioned in the original thread that adding pragma once to every header file in a commercial application that I work on sped up the build by 25%. That being said, I do agree we should test it in the boost libraries themselves, which is the first thing on my list of to-do's once I have time.

The big problem I have is that there is no evidence that #pragma once would actually help in practice. It helps in some super-special case, involving 200 basically empty files that all include each other and nothing else. I suspect (without any evidence) that if someone came along and said "I added #pragma once to the boost headers, and it sped up compilation by X% on windows, and didn't slow things down on linux / mac os x, and it didn't break any test or library", they might well get a less luke-warm response.
Indeed, and if Zach is able to come up with his script and run some tests that will hopefully lay the matter to rest one way or another. The only data point I have is that I did add #pragma once directives to the Boost.Math headers and it seemed to make no difference (a purely subjective opinion though), optimizing the template instantiations and use of MPL did have a much larger (ice subjectively noticeable) effect though. Other than that, careful use of precompiled headers has always been a much bigger win for me with msvc than any other approach... Just my unscientific 2c worth... John.

fwiw: I've done a few quick tests on a lib i'm working on (a Windows DLL built with VC9). The lib has 27 public headers which currently contain both normal include guards and #pragma once, and takes ~45 seconds to compile+link. I've tried building it with just include guards, and with just #pragma once, and theres no noticable difference between the build times. -- View this message in context: http://www.nabble.com/Proposal-for--pragma-once-support-tp23946014p23969069.... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Wed, Jun 10, 2009 at 12:13 PM, Richard Webb<richard.webb@boldonjames.com> wrote:
fwiw:
I've done a few quick tests on a lib i'm working on (a Windows DLL built with VC9).
The lib has 27 public headers which currently contain both normal include guards and #pragma once, and takes ~45 seconds to compile+link. I've tried building it with just include guards, and with just #pragma once, and theres no noticable difference between the build times.
I was going to suggest that a toy example showing that #pragma once is beneficial is useless. We need different, more concrete evidence, like "Adding #pragma once to boost::whatever headers improves compile times for the user by X%". Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

We have two factions here: 1. The old conservative, Windows-hating, folks, whose only drive, or boost, is that they type "boost" quite often. 2. The young pragmatic, "Do What Make Most People Happy", crowd. :-) PS: I belong to category 1, clearly. /David On Jun 10, 2009, at 11:39 AM, Sid Sacek wrote:
John and Pete,
I do appreciate your insights into the inner workings of the Boost community. I'm not discouraged about the lack of interest in my suggestion, but I was somewhat surprised. Boost libraries are one of those things that make life better for programming engineers. I believed that was the unwritten philosophy behind Boost, to "Make Life Better." Extending that philosophical notion, the Boost libraries would also know about the shortcomings of compilers and operating systems and help to improve their performance as well, simply because it "makes life better."
I suppose I must have been mistaken about that... perhaps not everybody in the Boost community has feelings of magnanimity and charity.
-Sid Sacek
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of John Phillips Sent: Tuesday, June 09, 2009 6:15 PM To: boost@lists.boost.org Subject: Re: [boost] "boost cold shoulder" (was proposal for #pragma oncesupport)
Pete Bartlett wrote:
I brought this topic up a couple of months ago, and I got the "Boost Cold Shoulder".
You see, I believe the head-honchos here are GCC aficionados and don't care much about Bill Gate's compilers.
I hope you do better than I did.
-Sid Sacek
I'm not any sort of honcho here so I hope you don't mind if I disagree.
I'm going to disagree, as well. I just went back into the archives and looked at your thread, and I'm confused by your perception of a cold
shoulder. I count 26 posts in the thread over less than 4 days, in a discussion that includes some library maintainers and one of the moderators. This a reasonably active discussion for around here.
I agree that no one showed up and said "You have permission, go ahead
and do it." However, as Pete points out, that just isn't the way Boost works. All broad action in Boost happens by first building a wide consensus in the community. If you notice, when moderators such as Dave or Beman have ideas for changes, they follow the same process of discussion on the list and building consensus. On some occasions they don't generate enough interest or agreement and their ideas go by the wayside. It isn't always quick, but it is the way Boost works.
More broadly, please continue contributing. Not every idea you have will be what the community does, but getting your ideas in the mix is central to how we function. (For the record, some of my ideas have gone down in flames, or just produced no broad interest, so I know where of I
speak.)
John
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

David, Why are you a "Windows Hater"? I've been programming since 1981, and have worked with many many compilers in my days. The Microsoft compilers have never disappointed me in any way since I started using them back in 1991. I believe I belong to a third category that you didn't mention below: 3. The middle-aged mellowed-out "try to always do the right thing", "using namespace boost", crowd. -Sid Sacek -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of David Bergman Sent: Wednesday, June 10, 2009 11:46 AM To: boost@lists.boost.org Subject: Re: [boost] "boost cold shoulder" (was proposal for #pragmaoncesupport) We have two factions here: 1. The old conservative, Windows-hating, folks, whose only drive, or boost, is that they type "boost" quite often. 2. The young pragmatic, "Do What Make Most People Happy", crowd. :-) PS: I belong to category 1, clearly. /David

On Thu, Jun 11, 2009 at 10:49 AM, Sid Sacek<ssacek@securewatch24.com> wrote:
The Microsoft compilers have never disappointed me in any way since I started using them back in 1991.
<flamebait> I found the prolonged lack of support for partial template specialization in vc6 & 7.0 to be *terribly* disappointing. </flamebait> But I'm not a hater. :-) Jon

On Jun 11, 2009, at 12:49 PM, Sid Sacek wrote:
David,
Why are you a "Windows Hater"?
I have been programming even longer than you, and have done a lot of Windows programming, using Win32, MFC (ugh), ATL, COM, .NET, blah, blah... I was simplifying matters a bit, and probably not completely non- ironically. I pointed out the factions as they are sometimes depicted by the people "on the other side" in these recent "Why can't you Boost guys accept our proposals that will make life better for so many!?" threads.
I've been programming since 1981, and have worked with many many compilers in my days. The Microsoft compilers have never disappointed me in any way since I started using them back in 1991.
Especially the ones starting with VC 7.1 are good. But their API's? Well, the CLI (ripoff of Java's API) is pretty good, but before that? There was a lot of reasons to dislike Windows programming with all those silly structs and long parameter lists, without good defaults. Well, this is getting "slightly" out-of-topic...
I believe I belong to a third category that you didn't mention below:
3. The middle-aged mellowed-out "try to always do the right thing", "using namespace boost", crowd.
Sounds like a reasonable and extensive category, even though it destroys my simplification ;-) /David
-Sid Sacek
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of David Bergman Sent: Wednesday, June 10, 2009 11:46 AM To: boost@lists.boost.org Subject: Re: [boost] "boost cold shoulder" (was proposal for #pragmaoncesupport)
We have two factions here:
1. The old conservative, Windows-hating, folks, whose only drive, or boost, is that they type "boost" quite often.
2. The young pragmatic, "Do What Make Most People Happy", crowd.
:-)
PS: I belong to category 1, clearly.
/David _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

2009/6/10 Sid Sacek <ssacek@securewatch24.com>:
I do appreciate your insights into the inner workings of the Boost community. I'm not discouraged about the lack of interest in my suggestion, but I was somewhat surprised. Boost libraries are one of those things that make life better for programming engineers. I believed that was the unwritten philosophy behind Boost, to "Make Life Better." Extending that philosophical notion, the Boost libraries would also know about the shortcomings of compilers and operating systems and help to improve their performance as well, simply because it "makes life better."
Your forgetting about the natural impulse to not want to clutter the code with unnecessary workarounds. Make no mistake, that's all it is, since #pragma once is the wrong feature to add to a compiler if you want to speed up header inclusion. It might be acceptable in proprietary code that never moves outside of Windows, but since Boost will still have to have normal include guards, #pragma once is just noise, semantically.
I suppose I must have been mistaken about that... perhaps not everybody in the Boost community has feelings of magnanimity and charity.
Wow, flamebait. And in a top post, too...

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Scott McMurray Sent: Wednesday, June 10, 2009 12:03 PM To: boost@lists.boost.org Subject: Re: [boost] "boost cold shoulder" (was proposal for #pragmaoncesupport)
Your forgetting about the natural impulse to not want to clutter the code with unnecessary workarounds. Make no mistake, that's all it is, since #pragma once is the wrong feature to add to a compiler if you want to speed up header inclusion.
It might be acceptable in proprietary code that never moves outside of Windows, but since Boost will still have to have normal include guards, #pragma once is just noise, semantically.
I agree with you about "noise". Then again, there is noise, and then, there is "NOISE". This might be noise: #pragma once But this really is NOISE #ifndef SOME_BLAH_BLAH_BLAH #define SOME_BLAH_BLAH_BLAH ... #endif What I ideologically want to see is this compromise between the two #pragma once( SOME_BLAH_BLAH_BLAH ) I think you can figure out what that means in compiler terms. But since that is not possible at this point in time, a compromise should be made; one that respects both Microsoft compiler users, and the non-Microsoft compiler users. I don't believe that Microsoft has the only compiler that improves its compile-times using #pragma once. So other compilers can also benefit from the #pragma usage as well. My personal experience with large projects is that #pragma once cuts the build time by 26%. Every little bit counts when you're working on very large applications. -Sid

2009/6/11 Sid Sacek <ssacek@securewatch24.com>
Your forgetting about the natural impulse to not want to clutter the code with unnecessary workarounds. Make no mistake, that's all it is, since #pragma once is the wrong feature to add to a compiler if you want to speed up header inclusion.
It might be acceptable in proprietary code that never moves outside of Windows, but since Boost will still have to have normal include guards, #pragma once is just noise, semantically. <snip> I think you can figure out what that means in compiler terms. But since that is not possible at this point in time, a compromise should be made; one that respects both Microsoft compiler users, and the non-Microsoft compiler users. I don't believe that Microsoft has the only compiler that improves its compile-times using #pragma once. So other compilers can also benefit from the #pragma usage as well. My personal experience with large projects is that #pragma once cuts the build time by 26%. Every little bit counts when you're working on very large applications.
A compiler that has a choice between #pragma once or #ifdef XXXXX should see that excluding parsing of the header could be done exactly the same on both, with the difference that the pragma is not generally supported and nonstandard. Any portable code will have to include the latter, making the first one completely pointless. Any speed benefit it gets you is the compiler builder not doing his/her job. Kind regards, Peter Bindels

On 11 Jun 2009, at 19:53, Peter Bindels wrote:
2009/6/11 Sid Sacek <ssacek@securewatch24.com>
Your forgetting about the natural impulse to not want to clutter the code with unnecessary workarounds. Make no mistake, that's all it is, since #pragma once is the wrong feature to add to a compiler if you want to speed up header inclusion.
It might be acceptable in proprietary code that never moves outside of Windows, but since Boost will still have to have normal include guards, #pragma once is just noise, semantically. <snip> I think you can figure out what that means in compiler terms. But since that is not possible at this point in time, a compromise should be made; one that respects both Microsoft compiler users, and the non-Microsoft compiler users. I don't believe that Microsoft has the only compiler that improves its compile-times using #pragma once. So other compilers can also benefit from the #pragma usage as well. My personal experience with large projects is that #pragma once cuts the build time by 26%. Every little bit counts when you're working on very large applications.
A compiler that has a choice between #pragma once or #ifdef XXXXX should see that excluding parsing of the header could be done exactly the same on both, with the difference that the pragma is not generally supported and nonstandard. Any portable code will have to include the latter, making the first one completely pointless. Any speed benefit it gets you is the compiler builder not doing his/her job.
Except it's a little trickier than that, as the compiler has to remember the guard, as it could get undefined in another file. Also, in C++ we have to be pragmatic. boost has huge amounts of infrastructure dedicated to get around quirks in different versions of different compilers. The real question is, will it improve real code? I suspect it might not, as I don't think compiling boost is slow because of opening files, it's slow because compilers have to chew their way through huge numbers of templates. Of course, real numbers are the only answer to this. Chris

On 10.06.2009, at 17:39, Sid Sacek wrote:
John and Pete,
I do appreciate your insights into the inner workings of the Boost community. I'm not discouraged about the lack of interest in my suggestion, but I was somewhat surprised. Boost libraries are one of those things that make life better for programming engineers. I believed that was the unwritten philosophy behind Boost, to "Make Life Better." Extending that philosophical notion, the Boost libraries would also know about the shortcomings of compilers and operating systems and help to improve their performance as well, simply because it "makes life better."
I suppose I must have been mistaken about that... perhaps not everybody in the Boost community has feelings of magnanimity and charity.
I think you are suggesting the wrong intentions here, which feels a little bit insulting. A small disclaimer: I picked your mail to reply, but it's also a general remake concerning the recent discussions on this list. I think you know what I mean :) So, please don't take it too personal as the answer might be a bit long for such a small insult. As maintainer of the Boost.Operators library and long-time Boost user and contributor I don't think we lack "charity" or something. The crucial point to understand what we are doing is this: We need to *balance* interests. What you and others (Christian S.) seem to miss is the fact that you can not just solve one problem and create another. Especially if that means to put the burden on other people. #pragma once is controversial because it's *not* just a no-brainer which "Makes Life Better.". Granted, it may make your life better. Even that of other VC++ users. But it creates more maintenance work, as we still need include guards for those compilers that don't support it, so the code won't get simpler, it will become more complex. It might also introduce new bugs for headers that may be included multiple times. If you use configuration macros, you need to include the configuration headers for each header that has an include guard/#pragma once. Increases compile-time, complexity, ... Coming from a VC++ perspective, you might not be aware of the drawbacks (because you *replace* your include guards with #pragma once) and that's OK, but please don't imply malice if we don't agree to your suggestions and ideas immediately. And please respect that fact that all perspectives need to be considered. We aim to solve all problems and drawbacks involved, and this is probably why it's so much work and why it is so hard. We don't compromise easily, which sometimes might look unhelpful. We nitpick on details, we explicitly try to find the holes in your ideas, etc. OTOH, I think this is what creates Boost's excellence. This is why Boost produced so many incredibly valuable things that even become standardized. It's the crucial difference to other libraries. That said, ask yourself: What could help to move the idea/suggestion on? How can you address/solve the drawbacks others see? Could we somehow combine include guards/#pragma once via macros to automatically make sure inconsistencies can't occur? What else can be done? Generally: Be constructive, improve you ideas/suggestions. That's the way to successfully participate in Boost, not by implying malice to others. Best regards, Daniel

On Wed, Jun 10, 2009 at 5:27 PM, Daniel Frey <d.frey@gmx.de> wrote:
As maintainer of the Boost.Operators library and long-time Boost user and contributor I don't think we lack "charity" or something. The crucial point to understand what we are doing is this:
We need to *balance* interests.
What you and others (Christian S.) seem to miss is the fact that you can not just solve one problem and create another. Especially if that means to put the burden on other people.
#pragma once is controversial because it's *not* just a no-brainer which "Makes Life Better.". Granted, it may make your life better. Even that of other VC++ users. But it creates more maintenance work, as we still need include guards for those compilers that don't support it, so the code won't get simpler, it will become more complex. It might also introduce new bugs for headers that may be included multiple times.
If you use configuration macros, you need to include the configuration headers for each header that has an include guard/#pragma once. Increases compile-time, complexity, ...
Coming from a VC++ perspective, you might not be aware of the drawbacks (because you *replace* your include guards with #pragma once) and that's OK, but please don't imply malice if we don't agree to your suggestions and ideas immediately. And please respect that fact that all perspectives need to be considered. We aim to solve all problems and drawbacks involved, and this is probably why it's so much work and why it is so hard. We don't compromise easily, which sometimes might look unhelpful. We nitpick on details, we explicitly try to find the holes in your ideas, etc.
OTOH, I think this is what creates Boost's excellence. This is why Boost produced so many incredibly valuable things that even become standardized. It's the crucial difference to other libraries.
That said, ask yourself: What could help to move the idea/suggestion on? How can you address/solve the drawbacks others see? Could we somehow combine include guards/#pragma once via macros to automatically make sure inconsistencies can't occur? What else can be done? Generally:
Be constructive, improve you ideas/suggestions.
That's the way to successfully participate in Boost, not by implying malice to others.
Most eloquently put Daniel - I wonder if it would be possible to include the gist of that text in some Boost header page or introductory page somewhere? There's a sentiment there that it would be useful to capture. - Rob.

On 9 Jun 2009, at 16:59, Zachary Turner wrote:
I would like to propose conditional support for #pragma once be added to all header files in boost. This would involve, at the beginning of every header file, a preprocessor check to determine whether or not the particular compiler is on a whitelist of known compilers to optimized #pragma once. If so, #pragma once is used. so, something like this:
Here are the build timings on my machine (Visual Studio 2008 Service Pack 2)
RedundantGuard - 1 second compile + link time PragmaOnce - 1 second compile + link time Nothing - 15 seconds compile + link time
Here are my build-timings on g++, Mac OS X. I had to remove 3 of the header files (I emptied the files Header197, 198 and 199) due to gcc complaining about include depth. I hope this won't effect things too much. I also had to change the return type of main to int. I compiled by doing "g++ main.cpp" Note that modern g++ does support '#pragma once' fine. I get the following results: RedundantGuard: 0.130s Nothing: 0.170s PragmaOnce: 0.710s So PragmaOnce is over 7 times slower. That time is almost entirely in the 'sys' column, so I suspect it querying files to check if they are identical or not. Chris

On Tue, Jun 9, 2009 at 11:33 PM, Christopher Jefferson < chris@bubblescope.net> wrote:
RedundantGuard: 0.130s Nothing: 0.170s PragmaOnce: 0.710s
So PragmaOnce is over 7 times slower. That time is almost entirely in the 'sys' column, so I suspect it querying files to check if they are identical or not.
Chris
I got the following timings on my laptop with g++ -c Main.cpp (4.3.2 on FC10): PragmaOnce real 0m0.776so user 0m0.158s sys 0m0.227s Nothing real 0m0.292s user 0m0.191s sys 0m0.040s RedundantGuard real 0m0.238s user 0m0.120s sys 0m0.038s

Chandrashekhar Kumar wrote:
On Tue, Jun 9, 2009 at 11:33 PM, Christopher Jefferson < chris@bubblescope.net> wrote:
RedundantGuard: 0.130s Nothing: 0.170s PragmaOnce: 0.710s
So PragmaOnce is over 7 times slower. That time is almost entirely in the 'sys' column, so I suspect it querying files to check if they are identical or not.
Chris
Did you check repeatablity of these measurements? Disk caches can significantly skew timings. Were these separate files with the various include guard techniques? If so is the disk fully defragged? Jeff

On 10 Jun 2009, at 02:13, Jeff Flinn wrote:
Chandrashekhar Kumar wrote:
On Tue, Jun 9, 2009 at 11:33 PM, Christopher Jefferson < chris@bubblescope.net> wrote:
RedundantGuard: 0.130s Nothing: 0.170s PragmaOnce: 0.710s
So PragmaOnce is over 7 times slower. That time is almost entirely in the 'sys' column, so I suspect it querying files to check if they are identical or not.
Chris
Did you check repeatablity of these measurements? Disk caches can significantly skew timings. Were these separate files with the various include guard techniques? If so is the disk fully defragged?
Yes, I ran each experiment 10 times and averaged. Just as a sanity check, I wrapped each #pragma once in a #ifdef BOOST_USE_PRAGMA_ONE, and then not defining it. As expected, the result is indistinguishable from the 'Nothing' choice. I just wanted to check it wouldn't confuse any kind of 'auto header- guard' detection gcc might have. Chris

Zachary Turner wrote:
I would like to propose conditional support for #pragma once be added to all header files in boost. This would involve, at the beginning of every header file, a preprocessor check to determine whether or not the particular compiler is on a whitelist of known compilers to optimized #pragma once. If so, #pragma once is used. so, something like this:
#if defined(_MSC_VER) /* || defined(OTHER_PRAGMA_ONCE_ENABLED_COMPILER) ... */ #pragma once #endif
If you are proposing to add this to every single file to boost, I am afraid you get to either do it, or provide a script to do this automatically. You might also have to patch the inspect program to automatically catch headers that don't have such preamble. Finally, you have to some form of the check that does not requires that every single header be updated if new compiler is added to white-list. Because Boost has >90 libraries now, there's zero chance to have such global change to happen unless you do necessary automation. And, it would be surely interesting if Boost itself can benefit from this approach, before we commit to it. - Volodya

On Tue, Jun 9, 2009 at 1:26 PM, Vladimir Prus <vladimir@codesourcery.com>wrote:
Zachary Turner wrote:
I would like to propose conditional support for #pragma once be added to all header files in boost. This would involve, at the beginning of every header file, a preprocessor check to determine whether or not the particular compiler is on a whitelist of known compilers to optimized #pragma once. If so, #pragma once is used. so, something like this:
#if defined(_MSC_VER) /* || defined(OTHER_PRAGMA_ONCE_ENABLED_COMPILER) ... */ #pragma once #endif
If you are proposing to add this to every single file to boost, I am afraid you get to either do it, or provide a script to do this automatically. You might also have to patch the inspect program to automatically catch headers that don't have such preamble. Finally, you have to some form of the check that does not requires that every single header be updated if new compiler is added to white-list.
Because Boost has >90 libraries now, there's zero chance to have such global change to happen unless you do necessary automation. And, it would be surely interesting if Boost itself can benefit from this approach, before we commit to it.
I agree that it would need to be automated. But the script itself should be very trivial, I'd be willing to try it myself. And perhaps the best approach is what I mentioned in a previous post, to force the programmer to explicitly define BOOST_USE_PRAGMA_ONCE before including a boost header file. This would solve the problem of having to modify every header when new compilers were released. And since by default it would be undefined, an out-of-the-box boost installation would work exactly as it does now. I'll work on this a bit later today perhaps, and try to post some benchmarks for for compiling boost itself, and for compiling a commercial product which uses boost.

Zachary Turner wrote On Tuesday, June 09, 2009 2:30 PM
And perhaps the best approach is what I mentioned in a previous post, to force the programmer to explicitly define BOOST_USE_PRAGMA_ONCE before including a boost header file. This would solve the problem of having to modify every header when new compilers were released.
I agree that a single manifest constant to control using #pragma once is the right thing to do. However, the scheme you describe here puts too much onus on the Boost user. Why not define that manifest constant on the compiler command line using Boost.Build? You can define that for each compiler, unless I'm much mistaken. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

On Tue, Jun 9, 2009 at 1:41 PM, Stewart, Robert <Robert.Stewart@sig.com>wrote:
Zachary Turner wrote On Tuesday, June 09, 2009 2:30 PM
And perhaps the best approach is what I mentioned in a previous post, to force the programmer to explicitly define BOOST_USE_PRAGMA_ONCE before including a boost header file. This would solve the problem of having to modify every header when new compilers were released.
I agree that a single manifest constant to control using #pragma once is the right thing to do. However, the scheme you describe here puts too much onus on the Boost user. Why not define that manifest constant on the compiler command line using Boost.Build? You can define that for each compiler, unless I'm much mistaken.
Having almost no familiarity whatsoever with Boost.Build, can you elaborate a little bit more? Are you referring to building the boost libraries themselves, or building a project that uses boost with a custom makefile, project, etc? I for one have never used Boost.Build - I downloaded a precompiled binary package from boostpro.com and use MSVC for building my own project, so does what you suggest still apply? Sorry if this is elementary, but like I said I have no familiarity at all with Boost.Build :)

Zachary Turner wrote: On Tuesday, June 09, 2009 2:55 PM
On Tue, Jun 9, 2009 at 1:41 PM, Stewart, Robert <Robert.Stewart@sig.com>wrote:
Zachary Turner wrote On Tuesday, June 09, 2009 2:30 PM
And perhaps the best approach is what I mentioned in a previous post, to force the programmer to explicitly define BOOST_USE_PRAGMA_ONCE before including a boost header file. This would solve the problem of having to modify every header when new compilers were released.
I agree that a single manifest constant to control using #pragma once is the right thing to do. However, the scheme you describe here puts too much onus on the Boost user. Why not define that manifest constant on the compiler command line using Boost.Build? You can define that for each compiler, unless I'm much mistaken.
Having almost no familiarity whatsoever with Boost.Build, can you elaborate a little bit more? Are you referring to building the boost libraries themselves, or building a project that uses boost with a custom makefile, project, etc?
It was a faulty idea since it would only affect the libraries with linked binaries. Given that most of Boost is header based, the idea is that the Boost user must change their own build system's command line to define that manifest constant. For those using Boost.Build to build their own code, the change I mentioned would apply automatically to building Boost libraries and the developer's own code. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Stewart, Robert wrote:
Zachary Turner wrote On Tuesday, June 09, 2009 2:30 PM
And perhaps the best approach is what I mentioned in a previous post, to force the programmer to explicitly define BOOST_USE_PRAGMA_ONCE before including a boost header file. This would solve the problem of having to modify every header when new compilers were released.
I agree that a single manifest constant to control using #pragma once is the right thing to do. However, the scheme you describe here puts too much onus on the Boost user. Why not define that manifest constant on the compiler command line using Boost.Build? You can define that for each compiler, unless I'm much mistaken.
That will not help somebody who includes boost headers in his project, I think. - Volodya

Vladimir Prus wrote On Tuesday, June 09, 2009 2:58 PM
Stewart, Robert wrote:
I agree that a single manifest constant to control using #pragma once is the right thing to do. However, the scheme you describe here puts too much onus on the Boost user. Why not define that manifest constant on the compiler command line using Boost.Build? You can define that for each compiler, unless I'm much mistaken.
That will not help somebody who includes boost headers in his project, I think.
Yeah, I realized that in another reply. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Zachary Turner wrote:
I agree that it would need to be automated. But the script itself should be very trivial, I'd be willing to try it myself. And perhaps the best approach is what I mentioned in a previous post, to force the programmer to explicitly define BOOST_USE_PRAGMA_ONCE before including a boost header file. This would solve the problem of having to modify every header when new compilers were released. And since by default it would be undefined, an out-of-the-box boost installation would work exactly as it does now. I'll work on this a bit later today perhaps, and try to post some benchmarks for for compiling boost itself, and for compiling a commercial product which uses boost. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
I have a dim memory that there used to be some libraries that did not have include guards, and would fail without them because of recursive use of headers. Is that still true, or am I hallucinating about it? This would complicate the script somewhat. John

On Tue, Jun 9, 2009 at 2:57 PM, John Phillips <phillips@mps.ohio-state.edu>wrote:
Zachary Turner wrote:
I agree that it would need to be automated. But the script itself should
be very trivial, I'd be willing to try it myself. And perhaps the best approach is what I mentioned in a previous post, to force the programmer to explicitly define BOOST_USE_PRAGMA_ONCE before including a boost header file. This would solve the problem of having to modify every header when new compilers were released. And since by default it would be undefined, an out-of-the-box boost installation would work exactly as it does now. I'll work on this a bit later today perhaps, and try to post some benchmarks for for compiling boost itself, and for compiling a commercial product which uses boost. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
I have a dim memory that there used to be some libraries that did not have include guards, and would fail without them because of recursive use of headers. Is that still true, or am I hallucinating about it?
This would complicate the script somewhat.
Err, did have include guards and would fail without, or did not have include guards and would fail with? If they have include guards and will fail without (which seems to be the 99.9% case) then pragma once shouldn't affect that. If they do not have include guards and must not have include guards, then yes this will complicate the script somewhat, but I'll try to figure it out anyway. Might take a day or two until I get a script working so I generate some benchmarks, but I'll post back once I do.

On Tue, Jun 9, 2009 at 9:57 PM, John Phillips<phillips@mps.ohio-state.edu> wrote:
Zachary Turner wrote:
I agree that it would need to be automated. But the script itself should be very trivial, I'd be willing to try it myself. And perhaps the best approach is what I mentioned in a previous post, to force the programmer to explicitly define BOOST_USE_PRAGMA_ONCE before including a boost header file. This would solve the problem of having to modify every header when new compilers were released. And since by default it would be undefined, an out-of-the-box boost installation would work exactly as it does now. I'll work on this a bit later today perhaps, and try to post some benchmarks for for compiling boost itself, and for compiling a commercial product which uses boost. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
I have a dim memory that there used to be some libraries that did not have include guards, and would fail without them because of recursive use of headers. Is that still true, or am I hallucinating about it?
Pretty much anything that uses Boost.Preprocessor with file iteration. And of course, Boost.Preprocessor itself. Also, IIRC, some libraries do not use boost.preprocessor directly, but implement some crude form of file iteration directly (which will also break). HTH, -- gpd

Giovanni Piero Deretta wrote:
On Tue, Jun 9, 2009 at 9:57 PM, John Phillips<phillips@mps.ohio-state.edu> wrote:
I have a dim memory that there used to be some libraries that did not have include guards, and would fail without them because of recursive use of headers. Is that still true, or am I hallucinating about it?
Pretty much anything that uses Boost.Preprocessor with file iteration. And of course, Boost.Preprocessor itself. Also, IIRC, some libraries do not use boost.preprocessor directly, but implement some crude form of file iteration directly (which will also break).
HTH,
Thanks for reading through my typo and getting to the point. John

I agree that it would need to be automated. But the script itself should be very trivial, I'd be willing to try it myself. And perhaps the best approach is what I mentioned in a previous post, to force the programmer to explicitly define BOOST_USE_PRAGMA_ONCE before including a boost header file. This would solve the problem of having to modify every header when new compilers were released. And since by default it would be undefined, an out-of-the-box boost installation would work exactly as it does now. I'll work on this a bit later today perhaps, and try to post some benchmarks for for compiling boost itself, and for compiling a commercial product which uses boost.
Thanks Zach, that would be really useful! John.

2009/6/9 Zachary Turner <divisortheory@gmail.com>
I would like to propose conditional support for #pragma once be added to all header files in boost. This would involve, at the beginning of every header file, a preprocessor check to determine whether or not the particular compiler is on a whitelist of known compilers to optimized #pragma once.
1. To make a case for using the non-portable #pragma once vs. portable include guards, you'll have to come up with metrics comparing #pragma once with include guards and show that #pragma once is significantly faster for the compilers listed at < http://www.boost.org/development/tests/release/developer/summary.html>. 2. When compilers get #pragma once wrong (as in < http://gcc.gnu.org/ml/gcc-bugs/2009-01/msg03268.html> earlier this year), who exactly is going to revert all of Boost back? 3. The semantics of #pragma once are different than the semantics of include guards (I believer that #pragma once tends to use the OS notion of identical files, and can fail under certain pathological cases). We would still need include guards everywhere for correctness. -- Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404

On 11 Jun 2009, at 19:40, Nevin :-] Liber wrote:
2009/6/9 Zachary Turner <divisortheory@gmail.com>
I would like to propose conditional support for #pragma once be added to all header files in boost. This would involve, at the beginning of every header file, a preprocessor check to determine whether or not the particular compiler is on a whitelist of known compilers to optimized #pragma once.
1. To make a case for using the non-portable #pragma once vs. portable include guards, you'll have to come up with metrics comparing #pragma once with include guards and show that #pragma once is significantly faster for the compilers listed at < http://www.boost.org/development/tests/release/developer/ summary.html>.
2. When compilers get #pragma once wrong (as in < http://gcc.gnu.org/ml/gcc-bugs/2009-01/msg03268.html> earlier this year), who exactly is going to revert all of Boost back?
3. The semantics of #pragma once are different than the semantics of include guards (I believer that #pragma once tends to use the OS notion of identical files, and can fail under certain pathological cases). We would still need include guards everywhere for correctness.
While I agree (1) needs doing, both (2) and (3) fall under the same category. I don't believe anyone is suggesting header guards be removed, and all bugs in #pragma once I've ever seen have involved multiple inclusions of a file, not skipping a file. Chris
participants (20)
-
Chandrashekhar Kumar
-
Christopher Jefferson
-
Daniel Frey
-
David Bergman
-
Emil Dotchevski
-
Giovanni Piero Deretta
-
Jeff Flinn
-
John Maddock
-
John Phillips
-
Jonathan Franklin
-
Nevin ":-]" Liber
-
Pete Bartlett
-
Peter Bindels
-
Richard Webb
-
Robert Jones
-
Scott McMurray
-
Sid Sacek
-
Stewart, Robert
-
Vladimir Prus
-
Zachary Turner