#pragma once vs include guards? [duplicate]
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.
When to use include guards or #pragma once C++
Summarizing the comment by Galik and what I realized:
Include guards should be put in every header file in the case that something in the future conflicts. Furthermore, the small time it takes the compiler to process the include guards will make the compilation faster since the extra header does not need to be processed.
Is #pragma once a safe include guard?
Using #pragma once
should work on any modern compiler, but I don't see any reason not to use a standard #ifndef
include guard. It works just fine. The one caveat is that GCC didn't support #pragma once
before version 3.4.
I also found that, at least on GCC, it recognizes the standard #ifndef
include guard and optimizes it, so it shouldn't be much slower than #pragma once
.
Why using both #pragma once and include guard? [duplicate]
Actually there might be a small difference inside the compiler. When compiler encounters #pragma once
then it can internally mark that this file is included. When it encounters #include
for this file for the second time it won't bother even to open it, it will just ignore the #include
statement.
With only include guard the preprocessor has to parse the whole file every time it's included to find a matching #endif
. Theoretically, if really complicated and large include files are included multiple times this can affect compilation time.
Other than that, include guard and #pragma once
behave the same way. Both of them are usually used because #pragma once
is not guaranteed to be supported on all compilers.
Edit:
Compiler might have the ability to detect that include guard's statements are surrounding the whole file's code and deduce that it's an include guard, producing exactly the same behavior as with #pragma once
. If that's the case then MSDN's claim is correct.
Difference between pragma once inside and outside include guards?
There's a subtle difference in that if SOME_HEADER_H
is already defined before the header is included, then in the second case the preprocessor will process the #pragma once
, and in the first case it won't.
You'll see a functional difference if you #undef SOME_HEADER_H
and include the file again by the same TU:
#define SOME_HEADER_H
#include "some_header.h"
#undef SOME_HEADER_H
#include "some_header.h"
Now, in case 1 I have all the definitions from the header file. In case 2 I don't.
Even without the #undef
, you could conceivably see a difference in preprocessing time due to the #pragma once
being ignored in case 1. That's up to the implementation.
I can think of two plausible ways it could already be defined before the first inclusion of this header file:
- (the obvious one) a completely separate file defines it, either deliberately or by accidental name clash,
- a copy of this file has already defined it. Depending on implementation that might include the case where this file gets involved in the same TU under two different filenames, e.g. because of a symbolic link or filesystem merge. If your implementation supports
#pragma once
, and you examine its documentation very carefully, you may be able to find a definitive statement whether the optimization is applied by the path under which the file is included, or by comparison of something which identifies a file's storage, like inode number. If the latter, you may even be able to figure out whether there are still scams that could be pulled to trick the preprocessor, such as remote-mounting a local filesystem to conceal that it's "the same file really"...
Used in the expected way, though, there's no difference provided that the implementation treats #pragma once
in the way that Microsoft defines it. As long as it's processed rather than skipped, it marks the containing file for the optimization, so it doesn't matter whether or not it would be processed on a second pass through the file -- the second pass won't happen.
And of course since the pragma is non-standard, at least in theory it could have a completely different meaning on different implementations, in which case it might matter when and how many times it is processed. In practice, you'd think nobody will do that.
Should I still use #include guards AND #pragma once?
It depends on how much portable your program is expected to be.
As long as you are writing a program which is supposed to work with compilers which you know definitely support #prama once
, just using #pragma once
should suffice. But doing so you restrict your program to set of compilers which support the implementation defined feature.
If you need your program to work on all compilers then you should use #pragma once
and include guards both.
In case a compiler does not support #pragma once
it will simply ignore it[Ref#1], in such a case the header guards will serve you the purpose, so nothing wrong in using them both when you are not aware of features supported by your target compilers.
So if you want your program to be 100% portable on different compilers the ideal way is still to use only the include guards. As @CharlesBailey rightly points out since the behavior for #pragma once
is implementation defined, the behavior on an unknown compiler might have a detrimental effect on your program.
[Ref#1]
Standard C++03: 16.6 Pragma directive
A preprocessing directive of the form
# pragma pp-tokensopt new-line
causes the implementation to behave in an implementation-defined manner. Any pragma that is not recognized by the implementation is ignored.
should pragma once be on top of every header as default
To me this suggest that I should start every header with #pragma once !!! Wich can't be right is it?
It can be right. Although it may in theory be a slight exaggeration.
Is it common practice?
Yes, it is. It is fairly universal if we include the other option of using a macro header guard into same practice.
If so, Is there a way to do that at compile time instead (as a flag for instance)?
If you mean, is there a way to make the pre-processor treat every included file as if they contained the pragma whether they have any form of header guard or not then no, there is no way to do that in C++.
In theory, you could write your own pre-processor that does this. However, although such pre-processor would be relatively simple, I would still consider that an unnecessarily complicated solution in relation to the benefit.
unless I add #pragma once reactively every time the problem pops up which seems "dirty" to me.
Is there a way to avoid the problem altogether?
There is a simple way to pre-emptively solve this problem, which you already mentioned: Add the pragma or a traditional macro header guard on top of every header file. There is no need to wait for problems to pop up. Just do this, and your worries are gone.
Related Topics
When and Why Will a Compiler Initialise Memory to 0Xcd, 0Xdd, etc. on Malloc/Free/New/Delete
What Uses Are There For "Placement New"
Passing a 2D Array to a C++ Function
Rule-Of-Three Becomes Rule-Of-Five With C++11
What Are Aggregates and Pods and How/Why Are They Special
Start Thread With Member Function
What Is the "--≫" Operator in C++
Is Gcc 4.8 or Earlier Buggy About Regular Expressions
How to Detect Unsigned Integer Overflow
What Are All the Common Undefined Behaviours That a C++ Programmer Should Know About
What Is "Argument-Dependent Lookup" (Aka Adl, or "Koenig Lookup")
How to Test Whether Stringstream Operator≫≫ Has Parsed a Bad Type and Skip It
Why Do People Say There Is Modulo Bias When Using a Random Number Generator
Why Have Header Files and .Cpp Files
Why Do I Get the Same Sequence For Every Run With Std::Random_Device With Mingw Gcc4.8.1