Discussion:
Standardize #pragma once or some equivalent
h***@gmail.com
2013-11-19 23:34:53 UTC
Permalink
It makes life easier, and just about every compiler supports it anyway--

Since #pragma is compiler specific, why not just call it #once

I see many projects still using *include guards,* which are error prone,
verbose, and ugly-- how embarrassing for C++*:(*

If, as is claimed, you want to make C++ easier to use, include guards must
go.

Thanks
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
David Krauss
2013-11-20 00:25:59 UTC
Permalink
Post by h***@gmail.com
It makes life easier, and just about every compiler supports it anyway--
Since #pragma is compiler specific, why not just call it #once
Ah, but then where does support go?
Post by h***@gmail.com
I see many projects still using *include guards,* which are error prone,
verbose, and ugly-- how embarrassing for C++*:(*
The only errors I have ever seen result from copy-paste from another
header, which is immediately caught because the new header gets ignored,
and omission, which afflicts #pragma once just as badly.

Verboseness is *good*. Ugly is an opinion.
Post by h***@gmail.com
If, as is claimed, you want to make C++ easier to use, include guards must
go.
Actually #pragma once is more subtle, because it requires the
implementation to establish identity of files residing at potentially
different paths. What degree of normalization is done, and what is
compared? The header-name token? The relative path the header was found
at? A canonicalized absolute path (some platforms may not support)? An
inode number (some platforms may not support)? A checksum of the actual
text within?

Even I'm not sure what GCC applies, and I'm trying to make a
preprocessor clone. It's sprinkled with comments that particular
functions don't normalize things, which hints that something else is
doing normalization. I haven't tried and seen. The docs claim it just
works, without being specific.

In terms of standardization, "just works" isn't very good. Why replace
perfectly well-defined behavior with something implementation-specific?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Tony V E
2013-11-20 01:01:00 UTC
Permalink
Note that there are subtle differences between pragma once and include
guards.

Typically pragma once uses absolute file path, whereas include guards uses,
well, include guards.
So if the same include is copied into two locations on disk, pragma once
will include it/them twice, include guards will include it only once
(effectively).

You can decide whether that is a big deal or not. But we could standardize
on md5 checksum or something as well...

Or maybe wait for modules...

Sent from my portable Analytical Engine

------------------------------
*From:* "***@gmail.com" <***@gmail.com>
*To:* "std-***@isocpp.org" <std-***@isocpp.org>
*Sent:* 19 November, 2013 6:34 PM
*Subject:* [std-discussion] Standardize #pragma once or some equivalent

It makes life easier, and just about every compiler supports it anyway--

Since #pragma is compiler specific, why not just call it #once

I see many projects still using *include guards,* which are error prone,
verbose, and ugly-- how embarrassing for C++*:(*

If, as is claimed, you want to make C++ easier to use, include guards must
go.

Thanks
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Jean-Marc Bourguet
2013-11-20 08:01:55 UTC
Permalink
Post by Tony V E
Note that there are subtle differences between pragma once and include
guards.
Typically pragma once uses absolute file path, whereas include guards
uses, well, include guards.
g++ for pragma once is using dev id + inode or something near as it won't
include twice something hard linked but will include twice something copied.

So if the same include is copied into two locations on disk, pragma once
Post by Tony V E
will include it/them twice, include guards will include it only once
(effectively).
You can decide whether that is a big deal or not.
If we replaced include guard by pragma once in our current code base, there
would be breakages. (One could argue that there is a need to rework our
code structure; I'd tend to agree if it didn't match the organizational one
and experience shows that having a mismatch between the two leads to more
important issues than the current state.)
Post by Tony V E
But we could standardize on md5 checksum or something as well...
Or maybe wait for modules...
That's what I would prefer. More precisely, I would not change the
preprocessor excepted for importing changes made first in the C standard
(the only potential exception I can think of is a way to better control the
scope of macro names).

Yours,

--
Jean-Marc
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Gabriel Dos Reis
2013-11-20 08:17:13 UTC
Permalink
Jean-Marc Bourguet <***@gmail.com> writes:

[...]

| If we replaced include guard by pragma once in our current code base, there
| would be breakages. (One could argue that there is a need to rework our code
| structure; I'd tend to agree if it didn't match the organizational one and
| experience shows that having a mismatch between the two leads to more important
| issues than the current state.)
|
|
| But we could standardize on md5 checksum or something as well...
|
| Or maybe wait for modules...
|
|
| That's what I would prefer. More precisely, I would not change the
| preprocessor excepted for importing changes made first in the C standard (the
| only potential exception I can think of is a way to better control the scope of
| macro names).

In a C++ world with modules, when and why would you need include guards
or pragma once in new codes?

-- Gaby
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Diego Sánchez
2013-11-20 09:24:56 UTC
Permalink
I've been browsing through N3347 (Modules), and it only mentions it in
section 2.3, and it's only a passing reference:

Note that import directives don't need include guards: A duplicated
import is essentially just ignored.

It does't mention any specific mechanism for it, so I assume that the
module name acts as an include guard itself. Can anyone shed some light on
this?
Post by Gabriel Dos Reis
[...]
| If we replaced include guard by pragma once in our current code base, there
| would be breakages. (One could argue that there is a need to rework our code
| structure; I'd tend to agree if it didn't match the organizational one and
| experience shows that having a mismatch between the two leads to more important
| issues than the current state.)
|
|
| But we could standardize on md5 checksum or something as well...
|
| Or maybe wait for modules...
|
|
| That's what I would prefer. More precisely, I would not change the
| preprocessor excepted for importing changes made first in the C standard (the
| only potential exception I can think of is a way to better control the scope of
| macro names).
In a C++ world with modules, when and why would you need include guards
or pragma once in new codes?
-- Gaby
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
h***@gmail.com
2013-11-20 16:48:43 UTC
Permalink
Well if modules will solve this, that is great..

.. but are modules still being worked on? It never gets any updates, and
the SG2 Modules forum is dead as a doorknob...
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Gabriel Dos Reis
2013-11-20 17:49:20 UTC
Permalink
***@gmail.com writes:

| Well if modules will solve this, that is great..
|
| .. but are modules still being worked on? It never gets any updates, and the
| SG2 Modules forum is dead as a doorknob...

There was a module evening session at the last Chicago meeting. It
didn't look dead to me.

-- Gaby
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Smith
2013-11-20 19:44:30 UTC
Permalink
Post by h***@gmail.com
Well if modules will solve this, that is great..
.. but are modules still being worked on? It never gets any updates, and
the SG2 Modules forum is dead as a doorknob...
Yes, it's still being worked on. There haven't been any papers for a while,
but there probably will be for the next meeting. Current activity includes
implementing a prototype modules system in Clang, in order to discover the
issues that the modules proposal will need to resolve.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
s***@gmail.com
2013-11-20 19:29:26 UTC
Permalink
Post by Tony V E
Note that there are subtle differences between pragma once and include
guards.
Nothing in the world precludes a slightly more explicit but still concise
feature, like

#guard my_unique_header_macro_identifier

which, if specified wisely, would be identical in all ways to the
ifdef/define/endif include guards (independent of file path, declares a
preprocessor token for testing elsewhere if needed, etc.) and has almost
all the advantages of #pragma once (minus the part where blindly
copy-n-pasting it into a new header probably won't "just work").

Whether it's worth adding is another story. Yes, modules will remove the
need in many ways, but modules don't completely remove the use of headers.
Put something like #guard into the next C standard and this even remains
useful long after C++ gains modules. I will just say that in several very
large projects I've worked on, #pragma once is just used everywhere since
it works fine for all our use cases and the include guard boilerplate is a
pain in the butt, but that's just my anecdotal evidence.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Andrew Tomazos
2013-11-20 23:42:32 UTC
Permalink
#pragma once support:

Clang <http://en.wikipedia.org/wiki/Clang>Supported[5]<http://en.wikipedia.org/wiki/Pragma_once#cite_note-5>Comeau
C/C++ <http://en.wikipedia.org/wiki/Comeau_C/C%2B%2B>Supported[6]<http://en.wikipedia.org/wiki/Pragma_once#cite_note-6>C++Builder
XE3<http://en.wikipedia.org/w/index.php?title=C%2B%2BBuilder_XE3&action=edit&redlink=1>
Supported[7] <http://en.wikipedia.org/wiki/Pragma_once#cite_note-7>Digital
Mars C++<http://en.wikipedia.org/w/index.php?title=Digital_Mars_C%2B%2B&action=edit&redlink=1>
Supported[8] <http://en.wikipedia.org/wiki/Pragma_once#cite_note-8>GCC<http://en.wikipedia.org/wiki/GNU_Compiler_Collection>
Supported[9] <http://en.wikipedia.org/wiki/Pragma_once#cite_note-9> (since
3.4[10] <http://en.wikipedia.org/wiki/Pragma_once#cite_note-10>)Intel C++
Compiler <http://en.wikipedia.org/wiki/Intel_C%2B%2B_Compiler>Supported[11]<http://en.wikipedia.org/wiki/Pragma_once#cite_note-11>Microsoft
Visual C++ <http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B>Supported
[12] <http://en.wikipedia.org/wiki/Pragma_once#cite_note-12>Pelles C<http://en.wikipedia.org/wiki/Pelles_C>
Supported[13] <http://en.wikipedia.org/wiki/Pragma_once#cite_note-13>IAR
C/C++<http://en.wikipedia.org/w/index.php?title=IAR_C/C%2B%2B&action=edit&redlink=1>
Supported[14] <http://en.wikipedia.org/wiki/Pragma_once#cite_note-14>It's
well and truly done. Files are disambiguated with their file id (inode on
unixes, FileIndex on windows).

The way the preprocessor interacts with the filesystem is technically
platform-specific, so the standard doesn't really comment on this - but big
deal. The feature is defacto standard.
-Andrew.
Post by h***@gmail.com
It makes life easier, and just about every compiler supports it anyway--
Since #pragma is compiler specific, why not just call it #once
I see many projects still using *include guards,* which are error prone,
verbose, and ugly-- how embarrassing for C++*:(*
If, as is claimed, you want to make C++ easier to use, include guards
must go.
Thanks
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
David Krauss
2013-11-21 00:24:51 UTC
Permalink
Post by Andrew Tomazos
The way the preprocessor interacts with the filesystem is technically
platform-specific, so the standard doesn't really comment on this - but big
deal.
The way the preprocessor finds files given arbitrary strings is
platform-specific. Checking file and/or pathname identity is a different
ballgame, and very difficult to do reliably. According to CERT (
*http://tinyurl.com/kc3gzvw* )
Post by Andrew Tomazos
Producing canonical file names for Windows operating systems is
extremely complex and beyond the scope of this standard. The best advice
is to try to avoid making decisions based on a path, directory, or file
name [Howard 2002
<https://www.securecoding.cert.org/confluence/display/seccode/AA.+Bibliography#AA.Bibliography-Howard02>].

Build systems do in fact use features like symlinks and multiple file
systems. Schisms probably exist between implementations of #pragma once
on the same platform. Given the de-facto standard, we can probably find
at least anecdotal feedback from library vendors who have attempted to
deploy it portably.

The solution is to use checksums, but that imposes a performance cost,
so it's not what's actually implemented.

Surely there's plenty of debate from the C working group we could
refer/defer to.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Andrew Tomazos
2013-11-21 00:46:49 UTC
Permalink
Post by Andrew Tomazos
The way the preprocessor interacts with the filesystem is technically
platform-specific, so the standard doesn't really comment on this - but big
deal.
The way the preprocessor finds files given arbitrary strings is
platform-specific. Checking file and/or pathname identity is a different
ballgame, and very difficult to do reliably. According to CERT ( *
http://tinyurl.com/kc3gzvw <http://tinyurl.com/kc3gzvw>* )
Post by Andrew Tomazos
Producing canonical file names for Windows operating systems is
extremely complex and beyond the scope of this standard. The best advice is
to try to avoid making decisions based on a path, directory, or file name [Howard
2002<https://www.securecoding.cert.org/confluence/display/seccode/AA.+Bibliography#AA.Bibliography-Howard02>
].
Build systems do in fact use features like symlinks and multiple file
systems. Schisms probably exist between implementations of #pragma once on
the same platform. Given the de-facto standard, we can probably find at
least anecdotal feedback from library vendors who have attempted to deploy
it portably.
On the unixes #pragma once is implemented by calling stat and comparing for
equality the st_dev and st_ino members.

On windows it is implemented by calling the GetFileInformationByHandle<http://msdn.microsoft.com/en-us/library/aa364952(v=vs.85).aspx> and
comparing for equality dwVolumeSerialNumber, nFileIndexHigh, nFileIndexLow

This follows both symlinks and hardlinks. Implementation variance is
highly doubtful.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Philipp Stephani
2013-11-23 16:17:30 UTC
Permalink
Post by Andrew Tomazos
Post by Andrew Tomazos
The way the preprocessor interacts with the filesystem is technically
platform-specific, so the standard doesn't really comment on this - but big
deal.
The way the preprocessor finds files given arbitrary strings is
platform-specific. Checking file and/or pathname identity is a different
ballgame, and very difficult to do reliably. According to CERT ( *
http://tinyurl.com/kc3gzvw <http://tinyurl.com/kc3gzvw>* )
Post by Andrew Tomazos
Producing canonical file names for Windows operating systems is
extremely complex and beyond the scope of this standard. The best advice is
to try to avoid making decisions based on a path, directory, or file name [Howard
2002<https://www.securecoding.cert.org/confluence/display/seccode/AA.+Bibliography#AA.Bibliography-Howard02>
].
Build systems do in fact use features like symlinks and multiple file
systems. Schisms probably exist between implementations of #pragma once on
the same platform. Given the de-facto standard, we can probably find at
least anecdotal feedback from library vendors who have attempted to deploy
it portably.
On the unixes #pragma once is implemented by calling stat and comparing
for equality the st_dev and st_ino members.
On windows it is implemented by calling the GetFileInformationByHandle<http://msdn.microsoft.com/en-us/library/aa364952(v=vs.85).aspx> and
comparing for equality dwVolumeSerialNumber, nFileIndexHigh, nFileIndexLow
And given that Windows + Unices is already a large part of the market, this
looks like a solved problem.
It would not be possible to put this into the standard, but instead of
making it completely implementation-defined, some restrictions could apply:

1. Header files referenced by the same file name in angle brackets are
always identical. (Or are there many cases where people write code that
includes different headers with the same name in angle brackets?)
2. Header files with different contents are never identical.
3. Everything else is implementation defined. Implementations are
encouraged to follow symbolic links and treat hard-linked files as
identical, if supported by the operating system and file system.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
xavi
2013-11-23 06:18:44 UTC
Permalink
In my experience, most often when two copies of a header are included, they
are actually different versions of the same header, so pragma once wouldn't
(and shouldn't) work, while include guards do.

Whether it's better to get both of them included (likely leading to an
error and a chance to fix your build system) or to get one of them more or
less randomly chosen is a matter of preference.
Post by Andrew Tomazos
Post by Andrew Tomazos
The way the preprocessor interacts with the filesystem is technically
platform-specific, so the standard doesn't really comment on this - but big
deal.
The way the preprocessor finds files given arbitrary strings is
platform-specific. Checking file and/or pathname identity is a different
ballgame, and very difficult to do reliably. According to CERT ( *
http://tinyurl.com/kc3gzvw <http://tinyurl.com/kc3gzvw>* )
Post by Andrew Tomazos
Producing canonical file names for Windows operating systems is
extremely complex and beyond the scope of this standard. The best advice is
to try to avoid making decisions based on a path, directory, or file name [Howard
2002<https://www.securecoding.cert.org/confluence/display/seccode/AA.+Bibliography#AA.Bibliography-Howard02>
].
Build systems do in fact use features like symlinks and multiple file
systems. Schisms probably exist between implementations of #pragma once on
the same platform. Given the de-facto standard, we can probably find at
least anecdotal feedback from library vendors who have attempted to deploy
it portably.
On the unixes #pragma once is implemented by calling stat and comparing
for equality the st_dev and st_ino members.
On windows it is implemented by calling the GetFileInformationByHandle<http://msdn.microsoft.com/en-us/library/aa364952(v=vs.85).aspx> and
comparing for equality dwVolumeSerialNumber, nFileIndexHigh, nFileIndexLow
This follows both symlinks and hardlinks. Implementation variance is
highly doubtful.
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Bo Persson
2013-11-28 16:16:08 UTC
Permalink
Post by xavi
In my experience, most often when two copies of a header are included,
they are actually different versions of the same header, so pragma once
wouldn't (and shouldn't) work, while include guards do.
Whether it's better to get both of them included (likely leading to an
error and a chance to fix your build system) or to get one of them more
or less randomly chosen is a matter of preference.
One big difference is that if you find that an include guard fails, you
can likely fix it by changing one guard string. When pragma once fails,
there is nothing much you can do about it.


Bo Persson
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
b***@gmail.com
2013-12-01 18:41:47 UTC
Permalink
Looking back at this discussion, there seems to be some discussion about
the merits of include guards vs. pragma once -- but not discussion whether
it would make sense to standardize this as a language feature. I don't
think anyone is saying that standardizing pragma once means that include
guards need to be deprecated -- include guards are still a fine way to
handle this problem, and they're still appropriate for many code bases.
However, I'd argue that the potential for a copy/paste mistake is higher
than the potential for build system confusion like this in most projects.

Support for this is around pretty much everywhere; and as a result it makes
sense to put into the standard, IMHO.

Has there been a formal proposal drafted for this?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
h***@gmail.com
2013-12-02 19:04:35 UTC
Permalink
I haven't seen any paper for it. Andrew presented some pretty good
evidence for getting it added though.
Modules might solve this, but the reality is that modules won't arrive
before C++17, and then add a few years for Microsoft's compiler...
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
Loading...