Date: Fri, 5 May 2023 11:57:30 -0400
On Fri, May 5, 2023 at 11:34 AM Marcin Jaczewski wrote:
> pt., 5 maj 2023 o 15:52 Jason McKesson napisał(a):
> > On Fri, May 5, 2023 at 4:16 AM Marcin Jaczewski <
> marcinjaczewski86_at_[hidden]> wrote:
> > > pt., 5 maj 2023 o 03:34 Jason McKesson napisał(a):
> > > >
> > > > On Thu, May 4, 2023 at 6:20 PM Marcin Jaczewski via Std-Proposals
> > > > <std-proposals_at_[hidden]> wrote:
> > > > >
> > > > > czw., 4 maj 2023 o 19:57 Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
> napisał(a):
> > > > > >
> > > > > > On Thu, May 4, 2023 at 1:29 PM Marcin Jaczewski <
> marcinjaczewski86_at_[hidden]> wrote:
> > > > > >>
> > > > > >> czw., 4 maj 2023 o 16:39 Arthur O'Dwyer napisał(a):
> > > > > >> > Marcin Jaczewski wrote:
> > > > > >> >>
> > > > > >> >> But attributes "failure" should be preferably "invisible"
> and "undetectable"?
> > > > > >> [...]
> > > > > >
> > > > > >> This means to have "portable" programs for both these
> attributes your
> > > > > >> headers need to have:
> > > > > >> ```
> > > > > >> #if !__atturibte_supported(no_unique_address) ||
> > > > > >> !__atturibte_supported(trivially_relocatable)
> > > > > >> #error "please install new compiler"
> > > > > >> #endif
> > > > > >> ```
> > > > > >
> > > > > > Yes, but that's true of literally everything in the language.
> You can't use structured bindings unless the compiler supports them. You
> can't use concepts unless the compiler supports them. You can't use
> `std::flat_map` unless the library supports it. And so on, and so on,
> forever. [...]
> > > > > > In other words, attributes aren't any more special than keywords
> in these respects. You can't use any of C++ without compiler support for it.
> > > > >
> > > > > But you miss again my point, I can use attributes like
> > > > > `[[fallthrough]]` even if the compiler does not know what it is,
> it's
> > > > > enough that my IDE knows it or other external tool.
> > > > > I can even use it in code that could be compiled in C++11 standard.
> > > > > This is why I name them "ignorable" (of course this does not apply
> to
> > > > > all as you did point out).
> > > > > This is why I would prefer if `no_unique_address` or
> > > > > `trivially_relocatable` would be contextual keyword as
> > > > > trying to compile it in an unsupported compiler will be hard error
> > > > > and there will be no problems with UB if some mixed TU are linked.
> > > >
> > > > You assume that a compiler will give a hard error if it doesn't
> > > > support it. Because `no_unique_address` is largely based on
> > > > unspecified behavior, an implementation can "support it" without
> > > > actually doing anything different. Changing that has nothing to do
> > > > with the syntax which invokes the behavior and has everything to do
> > > > with the behavior itself.
> > >
> > > I was comparing attributes to contextual keywords.
> > > if the compiler encounters some random `[[x]]` attribute then by
> definition
> > > it will skip over it, but if it encounters some random unexpected
> token `x` then
> > > it will signal a hard error.
> > >
> > > And yes, from a standard perspective NUA is an unspecified behavior,
> > > but from ABI
> > > perspective this is a critical one. If compiler is owner of ABI (like
> > > MSVC), then it can do anything he want with
> > > it, but if not then e.g. Itanium C++ ABI defines how this attribute
> should work.
> > >
> > > This means in case NUA or other similar functionality would be
> > > prefered to have hard error
> > > when the compiler does not know how to handle it.
> >
> > So what is the scenario we're talking about? It must be something
> > where you've written code that requires C++20 and you want the
> > compiler to error if it is being compiled in C++17 or before.
>
> Simple header file of my library that is publicly available, I compile
> dll using C++20
> and really on its features. And if some else grab by headers and try link
> to my dll I would prefer hard error if compiler do not support NUA or
> interpret it diffrent than my compiler.
>
So use:
- `__has_cpp_attribute(no_unique_address)`
- `-W3` or higher on MSVC <https://godbolt.org/z/jKh7TsYx8>, to diagnose
unrecognized or misspelled attributes (GCC and Clang diagnose by default,
even without `-Wall`)
- `static_assert` and/or unit-test, to ensure that the behavior you expect
to happen is, in fact, happening.
Both Marcin and Sebastian seem to be laboring under the incorrect
assumption that unrecognized C++ attributes are simply ignored by the
compiler, so that if the compiler doesn't support a particular attribute, *the
failure mode will be silent*. This is certainly wrong *today*, and in fact
I don't think it's *ever* been right. If the compiler silently ignored
"unknown" attributes, then you'd be in the horrible position that
struct S {
[[nouniqueaddress]] int x;
};
would silently Do The Wrong Thing, simply because you left off the
underscores.
In actual fact, the Standard deliberately reserves a namespace for standard
attributes (namely, any name not containing `::`), and compilers will
diagnose any misspelled or unrecognized attribute in that namespace.
In vendor-specific namespaces, the "morally right" behavior is more
confusing to reason about, but the facts on the ground are the same: All
three vendors treat [[unexpectednamespace::nouniqueaddress]] in exactly the
same way as [[nouniqueaddress]]. There's no way to turn on warnings for the
latter without also getting warnings for the former.
https://godbolt.org/z/9qbjzTd1d
So, if you misspell an attribute — or if you try to use an attribute that's
not supported by your compiler vendor, which comes to the same thing, from
the compiler's point of view — you'll get a diagnostic and have to fix your
code. This is the same thing that happens if you try to use any other new
syntax or compiler feature: If it's supported, your code works as intended.
If it's not supported, all bets are off; so we provide feature flags and
things that allow you to *engineer* around that situation.
–Arthur
> pt., 5 maj 2023 o 15:52 Jason McKesson napisał(a):
> > On Fri, May 5, 2023 at 4:16 AM Marcin Jaczewski <
> marcinjaczewski86_at_[hidden]> wrote:
> > > pt., 5 maj 2023 o 03:34 Jason McKesson napisał(a):
> > > >
> > > > On Thu, May 4, 2023 at 6:20 PM Marcin Jaczewski via Std-Proposals
> > > > <std-proposals_at_[hidden]> wrote:
> > > > >
> > > > > czw., 4 maj 2023 o 19:57 Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
> napisał(a):
> > > > > >
> > > > > > On Thu, May 4, 2023 at 1:29 PM Marcin Jaczewski <
> marcinjaczewski86_at_[hidden]> wrote:
> > > > > >>
> > > > > >> czw., 4 maj 2023 o 16:39 Arthur O'Dwyer napisał(a):
> > > > > >> > Marcin Jaczewski wrote:
> > > > > >> >>
> > > > > >> >> But attributes "failure" should be preferably "invisible"
> and "undetectable"?
> > > > > >> [...]
> > > > > >
> > > > > >> This means to have "portable" programs for both these
> attributes your
> > > > > >> headers need to have:
> > > > > >> ```
> > > > > >> #if !__atturibte_supported(no_unique_address) ||
> > > > > >> !__atturibte_supported(trivially_relocatable)
> > > > > >> #error "please install new compiler"
> > > > > >> #endif
> > > > > >> ```
> > > > > >
> > > > > > Yes, but that's true of literally everything in the language.
> You can't use structured bindings unless the compiler supports them. You
> can't use concepts unless the compiler supports them. You can't use
> `std::flat_map` unless the library supports it. And so on, and so on,
> forever. [...]
> > > > > > In other words, attributes aren't any more special than keywords
> in these respects. You can't use any of C++ without compiler support for it.
> > > > >
> > > > > But you miss again my point, I can use attributes like
> > > > > `[[fallthrough]]` even if the compiler does not know what it is,
> it's
> > > > > enough that my IDE knows it or other external tool.
> > > > > I can even use it in code that could be compiled in C++11 standard.
> > > > > This is why I name them "ignorable" (of course this does not apply
> to
> > > > > all as you did point out).
> > > > > This is why I would prefer if `no_unique_address` or
> > > > > `trivially_relocatable` would be contextual keyword as
> > > > > trying to compile it in an unsupported compiler will be hard error
> > > > > and there will be no problems with UB if some mixed TU are linked.
> > > >
> > > > You assume that a compiler will give a hard error if it doesn't
> > > > support it. Because `no_unique_address` is largely based on
> > > > unspecified behavior, an implementation can "support it" without
> > > > actually doing anything different. Changing that has nothing to do
> > > > with the syntax which invokes the behavior and has everything to do
> > > > with the behavior itself.
> > >
> > > I was comparing attributes to contextual keywords.
> > > if the compiler encounters some random `[[x]]` attribute then by
> definition
> > > it will skip over it, but if it encounters some random unexpected
> token `x` then
> > > it will signal a hard error.
> > >
> > > And yes, from a standard perspective NUA is an unspecified behavior,
> > > but from ABI
> > > perspective this is a critical one. If compiler is owner of ABI (like
> > > MSVC), then it can do anything he want with
> > > it, but if not then e.g. Itanium C++ ABI defines how this attribute
> should work.
> > >
> > > This means in case NUA or other similar functionality would be
> > > prefered to have hard error
> > > when the compiler does not know how to handle it.
> >
> > So what is the scenario we're talking about? It must be something
> > where you've written code that requires C++20 and you want the
> > compiler to error if it is being compiled in C++17 or before.
>
> Simple header file of my library that is publicly available, I compile
> dll using C++20
> and really on its features. And if some else grab by headers and try link
> to my dll I would prefer hard error if compiler do not support NUA or
> interpret it diffrent than my compiler.
>
So use:
- `__has_cpp_attribute(no_unique_address)`
- `-W3` or higher on MSVC <https://godbolt.org/z/jKh7TsYx8>, to diagnose
unrecognized or misspelled attributes (GCC and Clang diagnose by default,
even without `-Wall`)
- `static_assert` and/or unit-test, to ensure that the behavior you expect
to happen is, in fact, happening.
Both Marcin and Sebastian seem to be laboring under the incorrect
assumption that unrecognized C++ attributes are simply ignored by the
compiler, so that if the compiler doesn't support a particular attribute, *the
failure mode will be silent*. This is certainly wrong *today*, and in fact
I don't think it's *ever* been right. If the compiler silently ignored
"unknown" attributes, then you'd be in the horrible position that
struct S {
[[nouniqueaddress]] int x;
};
would silently Do The Wrong Thing, simply because you left off the
underscores.
In actual fact, the Standard deliberately reserves a namespace for standard
attributes (namely, any name not containing `::`), and compilers will
diagnose any misspelled or unrecognized attribute in that namespace.
In vendor-specific namespaces, the "morally right" behavior is more
confusing to reason about, but the facts on the ground are the same: All
three vendors treat [[unexpectednamespace::nouniqueaddress]] in exactly the
same way as [[nouniqueaddress]]. There's no way to turn on warnings for the
latter without also getting warnings for the former.
https://godbolt.org/z/9qbjzTd1d
So, if you misspell an attribute — or if you try to use an attribute that's
not supported by your compiler vendor, which comes to the same thing, from
the compiler's point of view — you'll get a diagnostic and have to fix your
code. This is the same thing that happens if you try to use any other new
syntax or compiler feature: If it's supported, your code works as intended.
If it's not supported, all bets are off; so we provide feature flags and
things that allow you to *engineer* around that situation.
–Arthur
Received on 2023-05-05 15:57:43