What are the differences (in performance, usability and functionality) in using #pragma once
and #if !defined MYHEADER_INCLUDED_
constructs? Or what is the difference between the two?
views:
255answers:
7Wikipedia has all your answers for this and is easy enough to find
In the C and C++ programming languages,
#pragma once
is a non-standard but widely supported preprocessor directive designed to cause the current source file to be included only once in a single compilation.Thus,
#pragma once
serves the same purpose as#include
guards, but with several advantages, including: less code, avoiding name clashes, and improved compile speed.
It has a more in-depth look at the advantages and disadvantages in the article. If you are really interested I suggest you read it completely, not just the blurb above.
- performance -- usually the
#pragma once
implementation compiles faster, because it's intent is clear - functionality -- both serve the same purpose -- to avoid more than one inclusion of a header file. The
defined
version has of course wider uses too, and if used carefully will allow to check in another file if the former was included (for conditional compilation for example) - usability -- if portability is not an issue go with
#pragma once
-- however, this is a non-standard extension
As Dan McG said, they are almost the same. But I don't recommend using #pragma unless in the cant-avoid things (like #pragma section) .It just make the code more non-standard.
And there is no functionality/performance issue. Because this is in compiling time. It might increase compiling time, but I didn't experience any difference!
While pragma once is superior in many aspects to #ifdef guards, it has one major flaw: it is based on file system paths: it uses the basic assumption that two different (absolute) paths are also two different files. Unfortunately this is not always true.
While it is not very likely you'll run into problem with this, it is something to be aware of.
As far as performance goes, I haven't measured it, but it's widely reported that compilers recognize the #include guard idiom and do not reopen/reprocess files that use it (therefore treating them the same as having used #pragma once
).
Other than that potential performance benefit (which probably doesn't exist), I see little that #pragma once
offers - it's somewhat more convenient when you create a new header - but guards really aren't that onerous to put in place. Since #pragma once
isn't particularly compelling and since I still occasionally deal with a compiler that doesn't support it, I use guards.
If it was shown that #pragma once
had a significant performance effect, I'd certainly start using it.
That said - I wish that C had been defined to only include headers once - unless some mechanism was invoked to indicate the header should be processed each time it was included. The times when you want that behavior are far, far out numbered by the times you don't (and I still come across headers every now and again that don't have guards or #pragma once
). But it wasn't defined that way, so include guards it is...
Some more background on this:
- Experiments with includes - Finding that #pragma once is faster than includes in Visual Studio 2003/2005
- Even more experiments with includes - Doing more investigation on different types of cases, very interesting series if you are into reducing build times.
#pragma once
is non standard.
If you're happy with the prospect of changing every single one of your header files when you discover your app or library won't build when you try to port it to a different platform, it's probably a good choice.
Otherwise, stick with #ifndef/#define/#endif
. Especially if you're building library code for other people to use.