C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Revising #pragma once

From: Jonas Christen <vaijnsxd_at_[hidden]>
Date: Tue, 27 Aug 2024 20:38:11 +0200
I think relative includes really would be a problem if #pragma once was
just looking at a files content and not its path or anything else at all.
It's not too uncommon to have a "main" header for just including other
headers (which can have pretty common names).
So something like this (somewhat similar to Sebastians example earlier)
would already fail:

// library_a/app.hpp
#pragma once
namespace library_a{ constexpr int execute(){ return 1; } }

// library_b/app.hpp
#pragma once
namespace library_b{ constexpr int execute(){ return 2; } }

// library_a/library_a.hpp (comments not part of the header)
// include guards with same behavior as pragma once based only on file
content would have
#ifndef FILE_HASH_ABC
#define FILE_HASH_ABC
#include "./app.hpp"
#include "./util.hpp"
#endif

// library_b/library_b.hpp (comments not part of the header)
// include guards with same behavior as pragma once based only on file
content would have
#ifndef FILE_HASH_ABC
#define FILE_HASH_ABC
#include "./app.hpp"
#include "./util.hpp"
#endif

// main.cpp
#include <string>
#include <iostream>
#include "./library_a/library_a.hpp"
#include "./library_b/library_b.hpp"

int main(int argc, char* argv[]){
    if(argc < 2)
        return -1;

    if(std::string{argv[1]} == "library_a")
        std::cout << library_a::execute() << "\n";
    else if(std::string{argv[1]} == "library_b")
        std::cout << library_b::execute() << "\n";

    // library_b::execute() is never declared
    // because library_a.hpp and library_b.hpp are identical
    // which leads to library_b/app.hpp never being included

    return 0;
}

On Tue, 27 Aug 2024 at 20:35, Jeremy Rifkin via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> > Yes, it does. It makes the behavior different from what is expected by
> majority of users. And is prone to subtle errors, if different headers
> happen to match in contents.
>
> The current behavior expected by the majority of users is hard to argue
> about because the semantics aren’t spelled out anywhere and every
> implementation does it differently. #pragma once represents the loose
> concept of single inclusion, and the semantics proposed here are not prone
> to the subtle errors of mtimes happening to match, symbolic or hard links
> not being handled well, certain filesystem mount behavior, or multiple
> copies of the same header being unintentionally included more than once
> (e.g. if a library header is copied around).
>
> There are few to no cases where you would want to include a file with the
> same exact contents with #pragma once multiple times. The only case
> presented here has to do with including a header of only macros then
> undefining everything then redefining. Such use probably shouldn’t be using
> an include guard in the first place and it’s important to note that
> traditional include guards might cause problems there too.
>
> Jeremy
>
> On Tue, Aug 27, 2024 at 12:28 Andrey Semashev via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> On 8/27/24 20:14, Jeremy Rifkin wrote:
>> > Does using contents for #pragma once break any practical or plausible
>> > uses of #pragma once? Does it have any clear downsides?
>>
>> Yes, it does. It makes the behavior different from what is expected by
>> majority of users. And is prone to subtle errors, if different headers
>> happen to match in contents.
>>
>> > I don’t think does. It should only make things more robust and portable.
>> >
>> > Jeremy
>> >
>> > On Tue, Aug 27, 2024 at 12:07 Andrey Semashev via Std-Proposals
>> > <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]
>> >>
>> > wrote:
>> >
>> > On 8/27/24 17:01, Jeremy Rifkin via Std-Proposals wrote:
>> > > Hi,
>> > > I have drafted a proposal for standardizing #pragma once. This has
>> > been
>> > > previously proposed a few years ago and I recognize that on top of
>> > being
>> > > difficult to standardize, existing opinions on this topic may
>> > render the
>> > > paper dead on arrival. However, due to its widespread nature and
>> > > concerns about portability contributing to it not being used more
>> I
>> > > think it's worth revisiting. I have uploaded the first draft at:
>> > >
>> >
>> https://jeremy-rifkin.github.io/cpp-proposals/drafts/pragma-once-draft-1.html
>> <
>> https://jeremy-rifkin.github.io/cpp-proposals/drafts/pragma-once-draft-1.html>
>> <
>> https://jeremy-rifkin.github.io/cpp-proposals/drafts/pragma-once-draft-1.html
>> <
>> https://jeremy-rifkin.github.io/cpp-proposals/drafts/pragma-once-draft-1.html
>> >>.
>> >
>> > I think, using file contents for `#pragma once` is wrong and should
>> not
>> > be standardized. The intended effect of `#pragma once` has always
>> been
>> > to avoid including *the same header* twice, not *the same content*.
>> >
>> > --
>> > Std-Proposals mailing list
>> > Std-Proposals_at_[hidden] <mailto:
>> Std-Proposals_at_[hidden]>
>> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>> > <https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals>
>> >
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2024-08-27 18:38:24