3

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?

Community
  • 1
  • 1
thb
  • 13,796
  • 3
  • 40
  • 68
  • 1
    I think it's nice that we have an effectively portable *de facto* standard on this. The gcc folks tried to break it once, tried to not support `#pragma once`, so maybe they are the ones who once stood in the way of standardization (just a guess, but seems reasonable). If so then I would further guess that they don't anymore, since g++ now has decent support (the pragma was un-deprecated in gcc 3.4). – Cheers and hth. - Alf Oct 26 '14 at 15:13
  • Unless the answer you are looking for is "because the committee didn't vote for it" I feel this question is primarily opinion-based. If that IS the answer you're looking for, then this question is not even about programming. – David Grayson Oct 26 '14 at 15:49
  • As a comment, for what it's worth: Because `#pragma once` is not in the standard, I personally avoid using it, even when it would otherwise make sense to use it. I do not assume that others who read my code should know nonstandard features like `#pragma once`. I want others to be able to read my code. Nevertheless, conventional inclusion guards remain fundamentally bug-prone, and are not a neat solution to the problem they are meant to address. – thb Oct 26 '14 at 18:12

2 Answers2

3

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
Community
  • 1
  • 1
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • 1
    "implementations generally do not deal with approaches to subvert the feature" that sounds like a made-up (construed) argument. The OP's whole point is that that argument simply doesn't carry weight. So I think it will be interesting to know, *who* proffers that argument? – Cheers and hth. - Alf Oct 26 '14 at 15:21
  • (I note in @DietmarKühl's profile that he is a frequent attendee of the C++ committee meetings.) – thb Oct 26 '14 at 15:24
  • 1
    Re point 2, the primary responsibility of a language standardization committee is, IMHO, to standardize existing practice, not to invent. I do hope that something good will come out of Daveed's module proposals. But that's a whole different kettle of fish, innovation, with a perspective of many years. – Cheers and hth. - Alf Oct 26 '14 at 15:26
  • 1
    @Cheersandhth.-Alf: you are free to read the standards proposals mailing list to see who chips in which arguments. The arguments above are those I recall from prior discussions without remembering any attribution. With respect to your second argument: this is a well-known and often refuted argument with its own long discussion. You are free to disagree with the assessment made by standardization groups and influence them correspondingly. You'd need to show up to do so, though. – Dietmar Kühl Oct 26 '14 at 15:27
  • I admit that your answer is not the answer *I* wanted, but that's all right. Personally, I agree with Alf. Your answer is informative and seems to be more or less correct, though, which is what matters. At any rate, your answer seems to be the best answer here, and is *accepted* for this reason. Thanks. – thb Oct 26 '14 at 17:59
  • @DietmarKühl: Re "[time] more reasonably spent", this is both a premature generalization and a false dichotomy, as I see it. Engaging in those two is a classic problem both in software development and in standardization work. *I am aware that you're just relating reasons as you perceive them, and that this is not necessarily your own view*; this comment is more of a dissenting view, a different take on the same facts, for readers who land here, rather than a debate with you. I regret very much that I do not yet have enough time to (again) participate where such debates go on. – Cheers and hth. - Alf Oct 27 '14 at 13:39
2

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

Community
  • 1
  • 1
gmas80
  • 1,218
  • 1
  • 14
  • 44
  • So, we should introduce an other *name* (as f.e. `#include_once`) to solve that. – Jarod42 Oct 26 '14 at 15:52
  • @Jarod42: no other name is needed. most every compiler supports #pragma once. there might theoretically be one that doesn't, but not one that assigns an incompatible meaning. – Cheers and hth. - Alf Oct 26 '14 at 17:55
  • I appreciate your effort to answer. Your answer, though well meant, answers a slightly different question than the one I had meant to ask. Nevertheless, it has sufficient useful content to merit an upvote. – thb Oct 26 '14 at 18:16