views:

1660

answers:

6

I'm working on a codebase that is known to only run on windows and be compiled under Visual Studio (it integrates tightly with excel so it's not going anywhere). I'm wondering if I should go with the traditional include guards or use #pragma once for our code. I would think letting the compiler deal with #pragma once will yield faster compiles and is less error prone when coping and pasting. It is also slightly less ugly ;)

Note: to get the faster compile times we could use Redundant Include Guards but that adds a tight coupling between the included file and the including file. Usually it's ok because the guard should be based on the file name and would only change if you needed to change in the include name anyways.

+8  A: 

I don't think it will make a significant difference in compile time but #pragma once is very well supported across compilers but not actually part of the standard. The preprocessor may be a little faster with it as it is more simple to understand your exact intent.

#pragma once is less prone to making mistakes and it is less code to type.

To speed up compile time more just forward declare instead of including in .h files when you can.

I prefer to use #pragma once.

See this wikipedia article about the possibility of using both.

Brian R. Bondy
According to wikipedia, some compilers optimize pragma once, some (like gcc) also optimize include guards. My gut says go with whatever system your code is already using. I use BOTH pragma once and guards.
KitsuneYMG
It can make a significant difference in compile time because the C preprocessor doesn't have to be involved - the compiler itself can decide not to even open the file. Opening files over and over takes cycles.
Donnie DeBoer
@Donnie - that is the optimisation which gcc's preprocessor applies to include guards. It automatically detects include guards in header files, and if there is one it treats the file as though it had #pragma once. If it's included again, and the include guard has not been undefined in the mean time, then the file is not re-opened or re-parsed.
Steve Jessop
True, but the question poster is using VC++, so using #pragma once may result in faster compilation.
Donnie DeBoer
Oh, I see what you mean. Sorry, I thought you were responding to kts's comment. About "some compilers (like gcc)". Clearly you're in fact responding to Brian's first sentence. Ignore me.
Steve Jessop
I put that bit about "some compilers" because I do not know what VC++ does (since I use both pragma once and guards) it has never mattered, and because MS could decide to remove/change pragma once behavior since it isn't required by the standard. Why they might do this I don't know, but it wouldn't be the first time they've made old code incompatible with new versions of Visual Studio.
KitsuneYMG
+1 for also pointing out the error-prone nature of include guards. I've seen them get copied and pasted before without appropriate adjustment - we didn't notice it for years until we tried to include the two headers together in one translation unit and it was a head scratcher given how long it had persisted. I dream of module support, but I'd still be very happy if a #pragma once equivalent became standard.
+6  A: 

If you're positive that you will never use this code anywhere other than Windows/VS, then you can certainly use #pragma once without worries.

You can also just use both (see example below), so that you get portability and compilation speedup on compatible systems

#pragma once
#ifndef _HEADER_H_
#define _HEADER_H_

...

#endif
Donnie DeBoer
#pragma once is well supported over many different compilers including GCC
Brian R. Bondy
true, but it's not ubiquitously supported. Include guards are always supported... depends on how portable you want your code to be.
Donnie DeBoer
I really don't want both, that just makes the code ugly. As long as portability isn't an issue I think code hygiene issues are next.
Matt Price
Portability isn't that much of a deal even if you did care about it. If you're currently writing for Windows-only, there are likely to be other things in your code that tie you more tightly to Windows than #pragma once. And if the day should ever come you do port some of the code, it wouldn't be hard to write a Perl script that went through your headers and replaced all uses of #pragma once with an include guard based on the file name and path.
Steve Jessop
On the other hand, if part of the project is writing bits which may eventually be usable elsewhere (e.g. math library, api wrapper, etc) go for portability. You're worrying waaay too much about how your code should LOOK and not about how it should WORK.... especially at the top of a file which people have learned to ignore anyway.
Sean
@onebyone: The only benefit to using #pragma once from the start is a potential performance boost. There would have to be a significant performance improvement to ever really want to move away from the "standard" way of protecting against multiple inclusions of a header. Clarity should come before performance by default - and in this case even the performance benefit is up for debate.
Richard Corden
+2  A: 

#pragma once allows the compiler to skip the file completely when it occurs again - instead of parsing the file until it reaches the #include guards.

As such, the semantics are a little different, but they are identical if they are used they way they are intended to be used.

Combining both is probably the safest route to go, as in the worst case (a compiler flagging unknown pragmas as actual errors, not just warnings) you would just to have to remove the #pragma's themselves.

When you limit your platforms to, say "mainstream compilers on the desktop", you could safely omit the #include guards, but I feel uneasy on that, too.

OT: if you have other tips/experiences to share on speeding up builds, I'd be curious.

peterchen
@Peterchen: It's wrong to state that a compiler needs to re-read the file for include guards. The first time the compiler parses the body it can record if the header had correct include guards. It can therefore skip the header if it is #included later. The key difference is that #pragma is not standard and if you ever need to use a compiler which doesn't support it then you're in a world of pain. The worse that can happen with include guards is that performance suffers very slightly.
Richard Corden
Not really a world of pain. You could fairly easily write a script that replaced all occurences of #pragma once with include guards.The worst that can happen with include guards isn't performance, its using misspelled #ifdefs or duplicating a file, changing the contents and forgetting to update the #ifdefs.
kibibu
+6  A: 

Until the day #pragma once becomes standard (that's not currently a priority for the future standards), I suggest you use it AND use guards, this way:

#ifndef BLAH_H
#define BLAH_H
#pragma once

// ...

#endif

The reasons are :

  • #pragma once is not standard, so it is possible that some compiler don't provide the functionality. That said, all major compiler supports it. If a compiler don't know it, at least it will be ignored.
  • As there is no standard behavior for #pragma once, you shouldn't assume that the behavior will be the same on all compiler. The guards will ensure at least that the basic assumption is the same for all compilers that at least implement the needed preprocessor instructions for guards.
  • On most compilers, #pragma once will speed up compilation (of one cpp) because the compiler will not reopen the file containing this instruction. So having it in a file might help, or not, depending on the compiler. I heard g++ can do the same optimization when guards are detected but it have to be confirmed.

Using the two together you get the best of each compiler for this.

Now, if you don't have some automatic script to generate the guards, it might be more convenient to just use #pragma once. Just know what that means for portable code. (I'm using VAssistX to generate the guards and pragma once quickly)

You should almost always think your code in a portable way (because you don't know what the future is made of) but if you really think that it's not meant to be compiled with another compiler (code for very specific embedded hardware for example) then you should just check your compiler documentation about #pragma once to know what you're really doing.

Klaim
Who said that #pragma once is ever going to be standard? Also, how many compilers don't track if the header file is completely surrounded in include guards? In otherwords - has anybody measured if #pragma once actually makes a difference in reality?
Richard Corden
@Richard, I have, and it does in cases - our project had 5500 includes with about 1/2 redundant.
280Z28
@Richard Yes performace have been tested by many people, the optimisation is at least present in VC and gcc. I didn't say that #pragma once will be standart, it's just a very big possibility as the standardisation process often consist of standardizing common feature/usage that are proven to be efficient, like #pragma once.
Klaim
@280Z28: Obviuosly a complete rebuild of 5500 includes with 50% being redundant is going to cost something. However, can you provide numbers, ie. using the pragma once compilation time (clean if you like) versus not using it. If you reach more than 1% of your total compliation time for a completely clean build I would be shocked.
Richard Corden
@Klaim: What you said was - "Until #pragma once becomes standard". The until there implies that it is going to happen but it is just a matter of time. However, C++ '0x has been in the works now for quite some time, and there have been discussions on the usual news groups about the standardisation of the feature. The conclusion was that an existing mechanism exists and so there was no need to add an alternative way of doing the same thing.
Richard Corden
@Klaim, 280Z28: Regarding performance, check out the following: http://gamesfromwithin.com/?p=32. Do either of you have numbers for a real project that show complete compile times for the project with and without #pragma once?
Richard Corden
@Richard - I'll fix the "until" problem as it seem to not be obvious, I just wanted to say that if it's standardized one day, then it will not be necessary to use the guards. For the performance numbers, I don't have some for my current home projects, but we did some after changing some company source code to use pragma once. The compilers were VC9/9 and CodeWarrior. I don't have the exact member but we had somethink like 10% speed compilation improvement. I'm not sure this is interesting, I think we can find numbers on the web or make some test yes, I'll try if I find enough time.
Klaim
By the way, the link you provide seems correct because the tests were made on "old" compiler, old enough to not have (Ithink) the optimizations we're talking about. A new test with recent compilers (vc8/9, last g++) would be a good thing indeed, to be sure about that. I agree that we should provide numbers, I don't have some right now.
Klaim
+5  A: 

I generally don't bother with #pragma once as my code sometimes does have to compile with something other than MSVC or GCC (compilers for embedded systems don't always have the #pragma).

So I have to use #include guards anyway. I could also use #pragma once as some answers suggest, but there doesn't seem to be much reason and it will often cause needless warnings on the compilers that don't support it.

I'm not sure what time savings the pragma might bring. I've heard that compilers generally already recognize when a header has nothing but comments outside of the guard macros and will do the #pragma once equivalent in that case (ie., never processing the file again). But I'm not sure if it's true or just a case of compilers could do this optimization.

In either case, it's just easier for me to use #include guards which will work everywhere and not worry about it further.

Michael Burr
+1  A: 

I think the first thing you should do is check to see if this is really going to make a difference, ie. you should first test the performance. One of the searches in google threw up this.

In the results page, the columns are sligthly off for me, but it's clear that at least up to VC6 microsoft was not implementing the include guard optimisations that the other tools were using. Where the include guard was internal it took 50 times as long compared with where the include guard was external (external include guards are at least as good as #pragma). But let's consider the possible affect of this:

According to the tables presented, the time to open the include and check it is 50 times that of a #pragma equivalent. But the actual time to do so was measured at 1 microsecond per file back in 1999!

So, how many duplicate headers will a single TU have? This depends on your style, but if we say that an average TU has 100 duplicates then in 1999 we're potentially paying 100 microseconds per TU. With HDD improvements this is probably significantly lower by now, but even then with precompiled headers and correct dependency tracking the total cumulative cost of this for a project is almost certainly an insigificant part of your build time.

Now, on the flip side, as unlikely as it may be, if you ever move to a compiler that doesn't support #pragma once then consider how much time will it take to update your entire source base to have include guards rather than #pragma?

There is no reason that Microsoft could not implement an include guard optimisation in the same way that GCC and every other compiler does (actually can anybody confirm if their more recent versions implement this?). IMHO, #pragma once does very little other than limit your choice of alternative compiler.

Richard Corden