C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Revising #pragma once

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Tue, 27 Aug 2024 22:06:12 -0400
On Tue, Aug 27, 2024 at 8:11 PM Ville Voutilainen <
ville.voutilainen_at_[hidden]> wrote:

> On Wed, 28 Aug 2024 at 02:54, Arthur O'Dwyer via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> > My experience matches Tiago's: #pragma once Just Works, in every
> environment I have access to.
> > But Gašper has said that his experience, in his environment, is
> different: #pragma once doesn't Just Work there. That is, to be precise,
> GCC handles the `#pragma once` syntax differently from how customers on
> that particular environment want it to be handled.
> >
> > It might be actually, practically useful, if someone with access to an
> environment like Gašper's, and GCC-hacking experience, would combine these
> to produce a compiler switch — something like `gcc
> -fpragma-once-hash-based`, or `-fpragma-once-timestamp-based`, or
> `-fpragma-once-something-else` — so that we could see what they are
> actually asking for. And then the GCC maintainers could consider whether to
> adopt an opt-in command-line switch like that. Then the few people in
> environments that require it, would put the switch into their build
> scripts, and then they could switch over to using `#pragma once` even in
> their environment.
> >
> > Right now I'm just seeing (a few) people saying "GCC's handling of
> #pragma once Doesn't Work for my environment," but with no concrete
> suggestions for how GCC ought to handle `#pragma once` in their environment.
>
> Well, we don't have such suggestions. We don't know whether they
> exist. Or, to phrase it differently, based on what we know, they
> don't.
> We are looking at a situation where you include the same header
> multiple times via different paths, but those paths involve bind or
> overlay mounts, and then the paths are different, the inodes are
> different, mtimes may be
> slightly different, and a #pragma once fails to recognize that we are
> looking at a header that's already been seen. You can then fall back
> on
> content hashing if you like, but that's much slower than parsing an
> include guard and skipping the file.
>
> In other words, the quick and efficient "is it the same file?" checks
> don't work, and the fallback that can give the correct answer is
> prohibitively expensive.


> The solution to the problem is the use of include guards, and
> avoidance of #pragma once.
>

Okay, IIUC as far as you're concerned, the answer is:

- What would *work*, theoretically, is a hash of the file contents. The
programmer could write `#pragma once // SOME_INCLUDE_GUARD_IDENTIFIER`,
thus making the hash different whenever the identifier was different; this
would have the same semantic effect as a full `#ifndef` include-guard. But,
as you say, this would likely be slower than just using a plain
include-guard. A plain include-guard wouldn't have to hash the whole file.
Now, a plain include-guard *would* still have to read the whole file in
order to find the `#endif`, because anything *after* the `#endif` would
need to be parsed as usual. (Remember, in this environment *the compiler
can't tell* if this is the same file that was encountered before, or a
different file that just happens to begin with a matching `#ifndef` line.)
Still, "basically grep" is likely to be measurably faster than "basically
md5sum".

- You reject the hash-the-contents solution; therefore, you will never ever
use `#pragma once`. Therefore it doesn't matter to your use-case whether we
standardize it (for environments-that-aren't-yours) or not.

*If* your experience matches Gasper's experience and
everyone-who-might-object-to-#pragma-once's experience, then it would
appear that there's no technical objection to standardizing `#pragma once`
for the environments that *do* support it (i.e. not yours).

–Arthur

Received on 2024-08-28 02:06:26