Traditionally, the standard and portable way to avoid multiple header inclusions in C++ was/is to use the #ifndef - #define - #endifpre-compiler directives scheme also called macro-guard scheme (see code snippet below).
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif
In most implementations/compilers (see picture below) however, there's a more "elegant" alternative that serves the same purpose as the macro-guard scheme called #pragma once. #pragma once has several advantages compared to the macro-guard scheme, including less code, avoidance of name clashes, and sometimes improved compile speed.
Doing some research, I realized that although #pragma once directive is supported by almost all known compilers, there's a turbidness on whether #pragma once directive is part of the C++11 standard or not.
Questions:
Could someone clarify whether #pragma once directive is part of the C++11 standard or not?
If it's not part of the C++11 standard, are there any plans on including it on later releases (e.g., C++14 or later)?
It would also be nice if someone could further elaborate on the advantages/disadvantages in using either one of the techniques (i.e., macro-guard versus #pragma once).
#pragma once is not standard. It is a widespread (but not
universal) extension, which can be used
if your portability concerns are limited, and
you can be sure that all of your include files are always on a local disk.
It was considered for standardization, but rejected because it
cannot be implemented reliably. (The problems occur when you
have files accessible through several different remote mounts.)
It's fairly easy to ensure that there are no include guard
conflicts within a single development. For libraries, which may
be used by many different developments, the obvious solution is
to generate a lot of random characters for the include guard
when you create it. (A good editor can be set up to do this for
you whenever you open a new header.) But even without this,
I've yet to encounter any problems with conflicts between
libraries.
Section §16.6 of the Standard (N3936 draft) describes #pragma directives as:
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.
Basically #pragma once is an implementation specific instance of a #pragma directive, and no, it's not standard. Yet.
It is often widely supported by most "major compilers" including GCC and Clang and is therefore sometimes recommended to avoid include-guards boilerplate.
Related
This question already has answers here:
Is #pragma once a safe include guard?
(15 answers)
Closed 5 years ago.
Modern C and C++ compilers support the non-standard #pragma once, preprocessor directive, which serve a similar purpose to the classic header guards:
#ifndef hopefully_unique_identifier_that_doesnt_hurt_the_code
#define hopefully_unique_identifier_that_doesnt_hurt_the_code
// some code here
#endif
One problem, I'm aware of, with the classic approach is that once you've included a header, you have to #undef the header guard macro to include it again (doing so, to me, is a major code-smell, but that's beside the point here). The same problem arises with the #pragma once approach, but without the possibility of allowing the header to be included more than once.
Another problem with the classic-approach is that you may, accidentally, define the same macro in unrelated places, thus either not including the header as expected or doing some other nasty stuff, that I can't imagine. This is reasonably easy to avoid in practice, by keeping to certain conventions such as basing the macros to UUID-like objects (i.e. random strings) or (the less optimal approach), basing them on the name of the file, they are defined in.
I have only rarely experienced any of these, potential problems, in real life, so I don't really consider them to be major problems.
The only potential real life problem I can think of with #pragma once, is that it's not a standard thing -- you're relying on something that may not be available everywhere, even if it is present, in practice, everywhere (*).
So, what potential problems exist with #pragma once, besides the ones I've already mentioned? Am I having too much faith in having it available, in practice, everywhere?
(*) Some minor compiler that only a handful of people use, excluded.
One problem I have encountered with using #pragma once was when including the same file that is located at multiple locations. With #pragma once it is deemed different, not with #ifndef/#define guard.
I have worked with a decent set of compilers so far:
GCC
Clang/LLVM
IBM XLC
Intel C++ Compiler
The only compiler that does not support #pragma once is the IBM XLC compiler, that that one does not even support C++11, so I am not interested. If you need to work with the IBM XLC Compiler on Blue Gene/Q, then you cannot use #pragma once.
A long time ago, certain compilers did not understand the include guard idiom and would repeatedly open the header file only to find that the preprocessor reduced the content to nothing. With these compilers, using #pragma once would give compile time benefit. However, this has been implemented in major compilers, such that this makes no difference nowadays.
Perhaps you have some special compiler for your embedded system. That one might be unable to use #pragma once.
In general I prefer #pragma once because when you duplicate a header file in order to do incremental refactoring by duplication or extending a class, you cannot forget to change the name of the include guard macro.
Therefore I do not know of any hard problem you have with #pragma once, except for certain compilers.
In using #pragma once you are giving up portability. You are no longer writing C or C++, but something allowed as a compiler extension.
That could cause you headaches if your code ever targets a different platform.
It's for this reason that I never use it.
Given that the name and location of a file is unique, I use that as my include guard. Furthermore because I have in the past targetted very old preprocessors, I use as a habit
#if !defined(foo)
#define foo 1
/*code*/
#endif
which has worked on every platform I've encountered since 1996.
Is it possible to portablize all #pragma commands? #pragma once can be portablize as the following:
#ifndef FOO
#define FOO
//Code here
#endif
However, I am not aware of universal implementations for #pragma pack and others. Is this possible?
The specification of pragmas in the standard is essentially an implementation-defined hook - the results of every pragma is implementation-defined. The results can include causing translation to fail, the implementation or emitted code behaving in a non-conforming manner (i.e. do things with any code construct differently than the standard requires). Implementations are required to ignore pragmas they don't recognise.
By definition, therefore, there are no universal definitions. There is also nothing preventing two different compilers from doing completely different things with the same pragma.
To "portabilize" such things, it is necessary to have a consistent specification of the features and behaviours that compiler vendors can implement (and, then, that programmers can consistently use). Getting such a specification is challenging but not impossible. Firstly, a specification needs to be shared - formally (e.g. in a standard) or informally (e.g. a specification agreed between some vendors, even if it is not actually in a standard). Second, it requires requires all vendors to agree to implement it - which is not a given, even if it is in a ratified standard. Third, it requires any variations between implementations to be understood, and accepted by developers (or, at the least, a reasonable majority).
When agreement is required between multiple players (vendors, developers, committees, the list goes on) it takes more effort to get agreement. With C++, there is no body that has sufficient "pull" to guarantee that some feature will be successfully "portabilized" - or, to put it another way, there is nobody with a trump vote who can be convinced to make something universal. Getting 100% "portabilization" will be hard - practically, there will often be a "near enough" result rather than 100%.
No, pragma implementations are left up to the preprocessor or compiler author and are not specified in the C++ Standard.
See https://isocpp.org/std/the-standard.
It's easier to read than one might expect.
What you posted will not result in precisely the same behavior. #pragma once in VS does not equate to the inclusion guard #ifdef you wrote.
The nonstandard #pragma once feature is implemented on practically all C++ compilers, but the C++ standard excludes it.
The usual explanation of why #pragma once, or some language construct that does what #pragma once does, has been excluded from the C++ standard is that hard links and copied header files either break #pragma once or provoke the compiler to heuristics. Fair enough, heuristics are normally incompatible with the C++ philosophy anyway, but regarding plain breakage: there are many useful language features you can break, not only #pragma once. The normal C++ way to manage such breakage is to let the compiler issue an optional warning in doubtful instances. After all, C++ is purposely designed to let one program unsafely and/or unportably when one wishes to do so. Besides, the unsafety and/or unportability of #pragma once is pretty minimal. It just isn't that easy to abuse.
Why is #pragma once excluded from the standard when other abusable but useful language features are typically included? Is there something special about #pragma once?
Also, where can one read the recent deliberations of the standards committee in the matter? Has some committee member, or committee follower, published a recent summary of the debate?
There are a few simple reasons:
It is harder than generally assumed to implement and specify it. The argument that it is implemented doesn't hold much water as the implementations generally do not deal with approaches to subvert the feature.
Committee time is much more reasonably spent on working on modules which make most of the preprocessor unnecessary than trying to improve something we want to get rid of.
There is a simple work-around around (include guards) for the absence of #pragma once, i.e., it isn't considered a problem.
It seems, existing implementations actually do behave different which seems to be the root of one of the recent discussions. Of course, this means that standardization would be good but then it immediately starts conflicting with 2. and the discussions won't be simple because different parties would want their respective behavior to be retained.
I didn't do a too thorough search but I didn't see a proposal, either: if nobody writes a proposal [and lobbies it through the process] nothing will be standardized. That said, I'd fully expect the reasons given above to stop a proposal to add #pragma once have a sufficient majority for it to be stopped quite quickly.
There was a recent discussion on the proposals mailing list (see isocpp.org for how to sign up; I can't get to this site at the moment, though). I didn't follow it too thoroughly, though. Quickly browsing over it I saw the four reasons given above (the forth I added after browsing).
Here are some references from the recent mailing list discussion:
Is #pragma once part of the standard?
Why isn't C/C++s #pragma once standard?
modules proposal
From my understanding, #pragma once is an implementation specific instance of the standard #pragma directive as described in Section §16.6 of the Standard (draft):
16.6 Pragma directive [cpp.pragma]
A preprocessing directive of the form
# pragma pp-tokens opt 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.
Having pragma once standardized would introduce quite a bit of complexity.
Give also a look here: https://stackoverflow.com/a/1696194/2741329
I have researched it online, someone said they are avoid to include the same file more then one time, but i still not clear enough the difference and the meaning of same file.
Thank you advance.
#pragma once is not part of the standard and may not work on all operating systems or compilers
#ifndef is the preferred method of only including a file only once on most OS
Other than that #pragma once is less prone to making mistakes that can be caused by forgetting to change header guards if you copy and paste code etc and it is less code to type.
In theory, #pragma once is platform specific and #ifndef style include guards are the only Standard compliant way to ensure header uniqueness through the preprocessor.
However, in practice, all major compilers (gcc, Clang, Visual C++, Intel) support it on all major platforms (Linux, Windows, MacOSX). Maybe some older or obscure compiler/platform combinations give you trouble, but in practice it just works. But caveat emptor!
The major advantage of using #pragma once is that it is a lot easier to do refactorings, since you don't have to either keep all the include guard names in sync with the file system (one common style guide obligation of defining header guards) or to use a pseudo-random string ID as include guard.
You can use #pragma once when you are addressing a specific compiler, #pragma once is non-standards and is specific to some specific C compilers whereas #ifndef/#define/#endif works on almost every C compiler. #pragma once reduces possibilities for bugs.
From wiki:
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, avoidance of name
clashes, and sometimes improved compile speed.1
Does including the same header files multiple times increase the compilation time?
For example, suppose every file in my project uses <iostream> <string> <vector> and <algorithm>. And if I include a lot of files in my source code, then does that increase the compile time?
I always thought that the guard headers served important purpose of avoiding double definitions but as a by product also eliminates double code.
Actually, someone I know proposed some ideas to remove such multiple inclusions. However, I consider them to be completely against the good design practices in c++. But was still wondering what might be the reasons of him to suggest the changes?
Most of these answers are wrong... For modern compilers, there is zero overhead for including the same file multiple times, assuming the header uses the usual "include guard" idiom.
The GCC preprocessor, for example, has special code to recognize the include guard idiom. It will not even open the header file (never mind reading it) for the second and subsequent #include directives.
I am not sure about other compilers, but I would be very surprised if most of them did not implement the same optimization.
Another technique besides precompiled headers is the compiler firewall idiom, explained here:
http://www.gotw.ca/publications/mill04.htm
http://www.gotw.ca/publications/mill05.htm
Every time #include <something.h> occurs in your source file, 'something.h' have to be found along the include path and read. But there is #ifndef _SOMETHING_H_ check, so the content of such something.h would not be compiled.
Thus there is some overhead, but it is really small.
If compile times were an issue, people used to use the optimisation recommended by Praetorian, originally recommened in Large Scale Software Design. However, most modern compilers automatically optimise for this case. For example, see the help from gcc
The best is to use precompiled headers. I do not know which compiler you are using, but most of them have this feature. I suggest you to refer to your compiler-manual on how to achieve this.
It basically collects all headerfiles and compiles it into a object file which then can be used by the linker. That speeds up compiling very much.
Minor Drawback:
You need to have 1 "uberheader" which is included in every compilation-unit (.cpp).
In that uberheader, only include static headers from libraries, not your own. Then the compiler does not need to recompile it very often.
It helps esp. when using header-only libraries such as boost or glm, eigen etc.
HTH
Yes, including the same header multiple times means that the file needs to be opened before the preprocessor guards kick in and prevent multiple definitions. The Mozilla source code uses the following trick to prevent this:
Foo.h
#ifndef FOO_H
#define FOO_H
// whatever
#endif /* FOO_H */
In all files that need to include foo.h
#ifndef FOO_H
#include "foo.h"
#endif
This prevents foo.h from having to be opened multiple times. Of course, this depends on everyone following a particular naming convention for their preprocessor guards.
You can't do this with standard headers, since there is no common naming convention for their preprocessor guards.
EDIT:
After reading your question again, I think you're asking about the same header being included in different source files. What I talked about above does not help with that. Each header file will still have to be opened and included at least once in every translation unit. The only way I know of to prevent this is to use precompiled headers, as #scorcher24 mentioned in his answer. But I'd stay away from this solution, because there is no standard way of generating precompiled headers across compilers, unless the compile times are absolutely prohibitive.
Some compilers, most notably Microsoft's, have a #pragma once directive that you can use to automatically skip an include file once it's already been included. This removes any performance penalty.
http://en.wikipedia.org/wiki/Pragma_once
It can be an issue. As others have said, most modern compilers
handle the case intelligently, and will only re-open the file in
degenerate cases. Most is not all, however, and one of the major
exceptions is Microsoft, which a lot of people do have to support. The
surest solution (if this is really a problem in your environment) is to
use the Lakos convention, putting the include guards around the
#include as well as in the header. This means, of course, a standard
convention for generating the guard names. (For external includes, wrap
them in your own header, which respects your local convention.)
Alternatively, you can use both the guards and #pragma once. The
guards will always work, and most compilers will avoid the extra opens,
and #pragma once will usually avoid the extra opens with Microsoft.
(#pragma once cannot be implemented reliably in complex networked
situation, but as long as all of your files are on your local drive,
it's quite reliable.)