Is #Pragma Once Part of the C++11 Standard

Is #pragma once part of the C++11 standard?

#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.

Why isn't C/C++'s #pragma once an ISO standard?

A directive like #pragma once is not trivial to define in a fully portable way that has clear an unambiguous benefits. Some of the concepts for which it raises questions are not well defined on all systems that support C, and defining it in a simple way might provide no benefit over conventional include guards.

When the compile encounters #pragma once, how should it identify this file so that it doesn't include its contents again?

The obvious answer is the unique location of the file on the system. This is fine if the system has unique locations for all files but many systems provide links (symlinks and hardlinks) that mean that a 'file' doesn't have a unique location. Should the file be re-included just because it was found via a different name? Probably not.

But now there is a problem, how is it possible to define the behaviour of #pragma once in a way that has an exact meaning on all platforms - even those that don't even have directories, let alone symlinks - and still get the desirable behaviour on systems that do have them?

You could say that a files identity is determined by its contents, so if an included file has a #pragma once and a file is included that has exactly the same contents, then the second and subsequent #includes shall have no effect.

This is easy to define and has well defined semantics. It also has good properties such that if a project is moved from a system that supports and uses filesystem links to one that doesn't, it still behaves the same.

On the downside, every time an include file is encountered containing a #pragma once its contents must be checked against every other file using #pragma once that has already been included so far. This implies a performance hit similar to using #include guards in any case and adds a not insignificant burden to compiler writers. Obviously, the results of this could be cached, but the same is true for conventional include guards.

Conventional include guards force the programmer to choose a macro that is the unique identifier for an include file, but at least the behaviour is well-defined and simple to implement.

Given the potential pitfalls and costs, and the fact the conventional include guards do work, it is not surprising to me that the standards committee didn't feel the need to standardize #pragma once.

What are the dangers of using #pragma once?

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.

c++ - Does #pragma once work on different Operating Systems?

The pragma is compiler dependent, if you use a compiler with support, it will work.

But for the moment, the usual recommendation is to use "pragma once" with headers guards.

This manner you ensure to include the file only once, and if pragma works, the compilation time will be improved.

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 isn't #pragma once automatically assumed?

There are multiple related questions here:

  • Why is #pragma once not automatically enforced?
    Because there are situations in which you want to include files more than once.

  • Why would you want to include a file multiple times?
    Several reasons have been given in other answers (Boost.Preprocessor, X-Macros, including data files). I would like to add a particular example of "avoid code duplication": OpenFOAM encourages a style where #includeing bits and pieces within functions is a common concept. See for example this discussion.

  • Ok, but why is it not the default with an opt-out?
    Because it is not actually specified by the standard. #pragmas are by definition implementation-specific extensions.

  • Why has #pragma once not become a standardized feature yet (as it is widely supported)?
    Because pinning down what is "the same file" in a platform-agnostic way is actually surprisingly hard. See this answer for more information.

#pragma once position: before or after #include's

#pragma once should be placed before any headers are included. Argument of #pragma directive is a subject to macro expansion. So content of included headers can alter the pragma behavior:

// whatever.hpp
...
#define once lol_no

// your_header.hpp
#include "whatever.hpp"

#pragma once // warning C4068: unknown pragma

#pragma once vs include guards?

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.

Since other abusable but useful features have been standardized, why not #pragma once?

There are a few simple reasons:

  1. 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.
  2. 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.
  3. There is a simple work-around around (include guards) for the absence of #pragma once, i.e., it isn't considered a problem.
  4. 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.
  5. 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:

  1. Is #pragma once part of the standard?
  2. Why isn't C/C++s #pragma once standard?
  3. modules proposal


Related Topics



Leave a reply



Submit