C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Revising #pragma once

From: Tiago Freire <tmiguelf_at_[hidden]>
Date: Mon, 23 Sep 2024 12:21:02 +0000
Here’s the summary of the discussion for those who missed it.

There are 2 camps, those that believe that “#pragma once” is better, and those who believe that it is worse.


  1. “#pragma once” is already in wide-spread use, and those who use it have a particular workflow that allows them to work. Understanding these workflows is imperative to the success of the proposal.
  2. Issues related to “#pragma once” integration are related to path duplication and rules about what constitute “same file”
  3. Those who use “#pragma once” have a proper environment control that prevents files from being duplicated across the filesystem. On this environment looking only at the file path alone is sufficient to resolve this ambiguity.
  4. Those who advocate for not using “#pragma once” have a build environment with issues related to content duplication in the filesystem.
  5. Hashing a file is pointless. It would actually break “#pragma once” for those currently using it, as “same file” does not mean “same content”.

Besides its painfully inefficient having to open the file, parse it, hash it, when you can just look at the file path and not even have to open the file.



As well intended as suggestions are, adding behavior to “#pragma once” besides “look at the file path”, helps absolutely no-one.
If you are at the point that you require “hashing”, you have build issues that no amount of behavior tunning is going to help you.

You would be supporting a setup that nobody uses, while making life miserable for everyone.

Back to point 1. “It is imperative to understand the build environments before making a suggestion”, otherwise you are just giving an opinion for the sake of giving an opinion, which is not productive.



  1. The reason why people in the camp of “no to #pragma once”, has little to do with the technical details, and no amount of arguing will ever be going to change their minds, ever, end of story.
The reason is because:

  1. They have build systems that are not properly curated and they can not avoid duplication of content in their builds, thus making usage of “#pragma once” unusable to them no matter the shape.
  2. They want to be able to bully 3rd party developers by saying “#pragma once is not part of the standard please change it”, forcing them to support their broken build setups, despite the fact that they get their libs for free and did not pay the developers. At the end of the day, nobody can force you to use “#pragma once” on your project if you don’t want to, the only issue occurs when other people use it on their projects.
And please don’t tell them that “the fact that there is no convention to how you define include guards, and developers can just tell them to bugger of after that, thus leading many to define the same macro on different projects that would for sure break builds and whose only remedy is to change source code”, and that this is by far worse.

So, in summary:

  1. No proposal should go beyond “same file (path)”
  2. You are not going to convince everyone, and you will get very strong opposition to it. But the standard works on “general consensus” and not “make everyone happy”. Either you like it or not, sooner or later the proposal will go trough when enough developers get (understandably) angry at this, and push it despite dissenting voices. Or modules come out and completely change the way you import external dependencies, thus making “#pragma once” obsolete. Whichever comes first.

Hope this clarifies.


From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf Of Jiri Bobek via Std-Proposals
Sent: Monday, September 23, 2024 1:22 PM
To: std-proposals_at_[hidden]p.org
Cc: Jiri Bobek <jiri.bobek_at_[hidden]>
Subject: Re: [std-proposals] Revising #pragma once

This should work the same way as include guards. Once the file is included, you don't include it second time.

Yes, utils.h may be a different file each time but that's irrelevant.

Hash works 🙂
On Mon, Sep 23, 2024, 12:55 Gašper Ažman via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>> wrote:
HASH DOES NOT WORK. There are reasons for this in this thread, but they boil down to this: you'd need to hash the entire reachable filesystem because #include's don't resolve the same way depending on where the file is accessed from on the filesystem.

#pragma once
#include "utils.h"

You'll see that header verbatim several times for different libraries in a translation unit and you'll miscompile. HASH DOES NOT WORK.

On Mon, Sep 23, 2024 at 10:28 AM Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>> wrote:
On Mon, Sep 23, 2024 at 9:04 AM Ville Voutilainen wrote:
>
> That's completely irrelevant, the build machine's newline handling can
> be whatever, as the content hash doesn't
> need to be the same on different machines.


I meant something like the following:

Leonardo has his Apple laptop, and he checks out code to
\\192.168.1.62\code\project1<file://192.168.1.62/code/project1>.
Donatello has his MS-Windows laptop, and he checks out code to
\\192.168.1.62\code\project2<file://192.168.1.62/code/project2>.

So Leonardo and Donatello have all of their code checked out to the
same network drive.

In Donatello's project, he has a source file containing the line:

    #include "../project1/monkey.hpp"

This header file has been checked out by Leonardo with Apple line
endings. But Donatello also has his own copy of "monkey.hpp" in his
own checkout, and one of Donatello's source files looks like this:

    #include "../project1/monkey.hpp"
    #include "common//monkey.hpp"

So the first directive gets the header file with "\r\n" line endings,
and the second directive gets it with "\n" line endings. And so if
we're going to be taking the hash of file contents, I think best to
normalise the line endings first (and also to remove trailing new line
characters).

Taking the hash of file contents might have too great an impact on
compile times though. If compile time weren't an issue though, then I
think taking the hash of file contents would be the optimal way to do
"#pragma once".
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]ocpp.org<mailto:Std-Proposals_at_[hidden]>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]g<mailto:Std-Proposals_at_[hidden]>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-09-23 12:21:08