C++ Logo

std-proposals

Advanced search

Re: [std-proposals] [Draft Proposal] Required attribute syntax

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Thu, 4 May 2023 21:34:13 -0400
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"?
> >> [...]
> >> I personally would prefer that you could disable attributes in one TU
> >> and still could link with the rest of the program that had enabled
> >> them.
> >> And I call this "ignorable" (same as `-O3` could be integrable but
> >> critical for any program).
> >> But of course currently standard do not work this way, and
> >> `[[no_unique_address]]` or `[[trivially_relocatable]]` would break if
> >> you link two TU that have diffrent interpretation of them.
> >
> >
> > Actually, [[trivially_relocatable]] has no direct effect on ABI at all; that's one of its design principles.
> > Now, in some sense, everything in the entire world — as long as it's observable — is ABI. Consider:
> >
>
> Ok, I mixed it with the similar Clang attribute that did affect the call ABI.
>
> > // https://godbolt.org/z/foxvdEsfP
> > struct [[trivially_relocatable]] S {
> > [[no_unique_address]] int i;
> > boost::container::vector<int> v;
> > };
> > inline int f() { return sizeof(S); }
> > inline bool g() { return std::is_trivially_relocatable_v<S>; }
> >
> > If you ignore the attributes in one TU, then `f` and `g` start returning 32 and 0 instead of 24 and 1; and since they're `inline` and need to have the same behavior in all TUs, that's an ODR violation.
> >
> > But [[trivially_relocatable]] deliberately doesn't affect ABI in any sense other than being observable via the type trait. It doesn't affect the calling convention, or size or alignment or mangling or anything like that. This makes [[trivially_relocatable]] one big step less ABI-ful than [[no_unique_address]], which directly affects struct layout and thus calling convention. (But it remains more ABI-ful than [[nodiscard]] or [[deprecated]], neither of which can even be used to create an ODR violation, as far as I know.)
> >
> >
> >> 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. We deal with this "dialectization" of C++ in at least a couple of ways:
> > - Feature-test macros, so you can portably tell whether your code will be accepted by the compiler with the semantics you expect. As you notice, we already have feature-test macros even for attributes, because in general their semantics do matter to working programmers.
> > - A general fear, in WG21, of "splitting the language" into dialects (e.g. `-fno-exceptions` or Embedded C++), which manifests as a resistance to "epochs"-type proposals and also as relentless pressure on vendors to implement everything in the current standard (and as close to "nothing else" as possible), so that code that uses exactly what's in the standard will be more-or-less "portable" across all vendors. This includes supporting the standard attributes.
> >
> > 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.
> >
> > –Arthur
>
> 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.

Received on 2023-05-05 01:34:25