C++ Logo


Advanced search

Re: [wg14/wg21 liaison] [isocpp-sg21] Telecon to review P2388R1 Minimum Contract Support: either Ignore or Check_and_abort

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Fri, 24 Sep 2021 09:22:55 +0200
On 24/09/2021 08.55, Andrzej Krzemienski via SG21 wrote:
> Aaron Ballman wrote:
> There's a third concern in the same vicinity related to the use of
> [[]]. We've spent a decade teaching programmers that the positional
> placement of [[]] matters as to how it is interpreted by the compiler.
> void func(int i) [[attr]]; // attribute appertains to the function type
> void func(int i) [[contract:]]; // no impression that this impacts the
> type, but not certain either
> So if contracts don't behave like type attributes (which the standard
> doesn't currently make use of), it negates a lot of the educational
> effort on how to properly use attributes. Even though the standard
> doesn't use type attributes, users can use them with vendor specific
> attributes. For example, function type attributes are known to impact
> things like type checking; e.g., https://godbolt.org/z/3YzGb897f <https://godbolt.org/z/3YzGb897f>
> Aaron Ballman also wrote:
> Speaking as not-your-liaison but as the person responsible for
> attribute implementations in a few C++ compilers, this particular
> concern is not my biggest concern with the syntax. I'm *way* more
> concerned about the fact that these look like attributes when they're
> not actually attributes. This attribute-like syntax, coupled with
> where you write contracts, makes it *look* like the user has written a
> type attribute when the semantics of the contracts behave more like a
> declaration attribute. This muddies the language too much for me to
> support. One of the big reasons we got the [[]] syntax for attributes
> in the first place was because of known problems with attribute
> appertainment "sliding" to whatever construct makes most sense based
> on the spelling of the attribute, and that's essentially all this
> syntax achieves.
> I need some help understanding what is considered a proper usage of a "type attribute" in the context of function declaration.
> It is quite easy to see in variable declarations: if one declaration declares multiple variables, the type attribute would affect all the variables.
> But in case of a function declaration, there is only one function being declared at a time.


using F = int(int);

F f1, f2, f3;

int main()
  f1(5); // ok

An attribute appertaining to the function type would be declared like that:

using F = int(int) [[whatever]];

and indicate that the attribute applies to all three functions f1,f2,f3
declared with that type.

That's similar to an extended alignment on a class type, for example:
It applies to all objects of that class type.

> You gave an example with [[gnu::fastcall]], and here the situation is quite clear: it affects function type to the degree that I cannot cast it to a pointer that doesn't have [[gnu::fastcall]].
> But is this a determining factor? An attribute shall appertain to function type if it modifies the type of the function?

Yes, that was the original motivation here. If it just affects the particular
function, it should appertain to the declarator-id; if it affects the type, it
should appertain to the function type.

We have later established the policy that standard attributes, when ignored,
don't make a program ill-formed or semantically ill-behaved, but that policy
wasn't clear when attributes were first established (plus we have vendor
attributes that violate that, such as the mentioned gcc one).

Given that pre/postconditions are not intended to modify the function type
(although there might be some abstract viewpoint that does consider them
part of the type), pre/postconditions, when viewed as attributes, don't
belong where they're currently placed in the syntax.

A non-attribute-looking syntax would alleviate that concern.


Received on 2021-09-24 02:23:06