I'm on vacation so my response will be somewhat short and I probably
won't re-engage until January. More below.

On Wed, Dec 17, 2025 at 5:57 AM Alejandro Colomar <[email protected]> wrote:
>
> Hi Paul,
>
> Context for those newly CCed:
> <https://lists.gnu.org/archive/html/bug-gnulib/2025-12/msg00133.html>
>
> On Wed, Dec 17, 2025 at 12:03:40AM -0800, Paul Eggert wrote:
> > On 2025-12-16 03:53, Alejandro Colomar wrote:
> >
> > > See the following program, to understand all the placements.  I've used
> > > attributes that don't make sense, to trigger diagnostics, which make it
> > > more visible to what they apply.
> > >
> > >     alx@devuan:~/tmp$ cat attr.c
> > >     [[gnu::packed]] void f(void), g(void);  // Attributed:  f, g
> > >     void [[gnu::packed]] h(void);  // Attributed:  void
> > >     void i [[gnu::packed]](void);  // Attributed:  i
> > >     void j(void) [[gnu::packed]];  // Attributed:  void(void)
> > >
> > >     [[pure]] enum a {A} v, vv;  // Attributed:  v, vv
> > >     enum [[pure]] b {B} w;  // Attributed:  enum b
> > >     enum c [[pure]] {C} x;  // Syntax error
> > >     enum d {D} [[pure]] y;  // I think this won't work.

I think the C standard has a bug here. As I see it, a
specifier-qualifier-list allows an attribute after a
type-specifier-qualifier (and an enum-specicier is a type-specifier).
I'm not seeing a semantic restriction to make this invalid. This seems
like it could be accidental because C++ (where this feature
originated) makes a distinction between defining type specifiers and
non-defining ones. I've not investigated though, but this does lead to
what I consider to be a rather odd situation:
https://godbolt.org/z/ndE9cqoYf (note the AST dump where `enum f` is
attributed!).

I agree with your analysis of all the other positions though.

> > >     enum e {E} z [[pure]], zz;  // Attributed:  z
> >
> > These examples unfortunately confused me more than they helped. They would
> > be better if they used attributes that made sense for what's being declared.
> > For example:
> >
> >   enum d {D} [[pure]] y;
> >
> > conforms to C23 and so "works" in some sense. However, GCC rightly issues
> > two warnings for it because it is dubious for one reason (the [[pure]]
> > applies to y's type, but not to enum d in general) and dubious for another
> > (types can't be pure).
>
> I did that precisely so that you see diagnostics.  Those diagnostics
> tell you what you were trying to apply the attributes to, which confirms
> the rules I mentioned about placement of the attributes.
>
> If you want something that will (mostly) work, you could check
>
>         [[gnu::unavailable]] int f(void), g(void);  // Attributed:  f, g
>         int [[gnu::aligned(8)]] h(void);  // Attributed:  int
>         void i [[gnu::unavailable]](void);  // Attributed:  i
>         int j(int) [[gnu::aligned(8)]];  // Attributed:  int(int)
>
>         [[gnu::aligned(8)]] enum a {A} v, vv;  // Attributed:  v, vv
>         enum [[gnu::aligned(8)]] b {B} w;  // Attributed:  enum b
>         enum c [[gnu::aligned(8)]] {C} x;  // Syntax error
>         enum d {D} [[gnu::aligned(8)]] y;  // Attributes can't go here
>         enum e {E} z [[gnu::aligned(8)]], zz;  // Attributed:  z
>
> > Also, there are exceptions to the guidelines that you gave. For example,
> > "[[fallthrough]];" doesn't follow the guidelines.
>
> [[fallthrough]] is an *aberration*.

lol

> It should have never been an
> attribute, because, as you see, it doesn't attribute anything.

It is an attribute-declaration. See 6.7.1p1 and p10. This was done to
make the grammar a bit easier to understand, in C++ it's attributing a
null statement instead.

> fallthrough is a jump statement misusing the syntax of an attribute.

Incorrect. It is not a jump statement, it has no semantic effect. See 6.7.13.6

> It should have been 'fallthrough;', with syntax similar to 'continue;'
> et al..  What it does is best described as "jump to the next 'case'",
> with a constraint that the statement must be the last statement at the
> top-level of a 'case'.

No, it really does not. It's a hint to the compiler saying "the
semantics of this code is intended". It's not a jump to the next case
in the same way that a semi colon is not a jump to the next statement;
it's following the flow of execution laid out by the abstract machine.

> I've CCed Aaron (maintainer of Clang), who added [[fallthrough]] in
> 2019.
>
> The problem comes from the fact that in C23 (inherited from C++),
> attributes were (are) ignorable.  Ignorability is nonsensical in
> attributes, and seems only present because of DoD compilers that wanted
> to entirely ignore features they wouldn't want to implement (to save
> money),

Incorrect, this is a requirement that the committee felt was so
important that it encoded it in the standard.

> AFAIK.  However, after the fact, some members of the committee
> have started misusing attributes as "comments with optimization and/or
> diagnostic hints", just because this broken ignorability made them
> effectively that.

Incorrect.

> I'm working on a proposal to fix attributes (see below) so that they're
> not comments anymore.  Aaron seems to be okay with that proposal.

I have no idea where you got that impression, but it's not something
I'm okay with; I think your proposal is an overreach into
implementation QoI. There's already a *ton* of information out there
on why, so I won't bother to repeat it here.

~Aaron

> I've also CCed Joseph, who doesn't agree yet with it.
>
> I also want to write a proposal to make fallthrough a proper jump
> statement.  I floated the idea in the committee, and some members were
> in favour of this, but I haven't written a paper yet.
>
> Ignoring fallthrough, the guidelines become consistent.
>
>
> Have a lovely day!
> Alex
>
> ---
> Name
>         alx-0011r12 - diagnose unsupported attributes (Earthly Demon)
>
> Principles
>         -  Codify existing practice to address evident deficiencies.
>
> Category
>         Attributes
>
> Author
>         Alejandro Colomar <[email protected]>
>
>         Cc: Jens Gustedt <[email protected]>
>         Cc: Aaron Ballman <[email protected]>
>         Cc: Joseph Myers <[email protected]>
>         Cc: Alex Celeste <[email protected]>
>         Cc: Martin Uecker <[email protected]>
>
> History
>         <https://www.alejandro-colomar.es/src/alx/alx/wg14/alx-0011.git/>
>
>         r0 (2025-04-01):
>         -  Initial draft.
>
>         r1 (2025-04-02):
>         -  Add stdc:: attributes, and make them like vendor ones, in
>            that they're allowed to change validity and semantics of a
>            valid program.  Revert changes to prefixless attributes.
>            Adapt names.
>
>         r2 (2025-04-02):
>         -  Add __stdc__:: variant.
>         -  Fix typos.
>         -  Make it a constraint violation to use an unsupported stdc::
>            attribute.
>         -  Define 'standard prefixed attributes'.
>
>         r3 (2025-05-04; n3576):
>         -  tfix.
>         -  wfix.
>         -  Rebase on n3550.
>
>         r4 (2025-06-27):
>         -  Reserve the standard prefixed attribute tokens.
>         -  Support for them is optional, BTW.
>
>         r5 (2025-06-30; n3631):
>         -  Note that the last parenthetical of 6.7.13.1p1 is redundant
>            with a constraint specified in 6.7.13.2p2, and thus remove it
>            without replacement.
>         -  Add a similar constraint for the standard prefixed
>            attributes.
>         -  Change the proposal name to be more consistent with the
>            current proposal.
>
>         r6 (2025-07-04):
>         -  Fix incorrect uses of terminology.
>         -  tfix.
>
>         r7 (2025-07-04; n3661):
>         -  Clarify sentence with context.
>         -  tfix.
>
>         Brno (2025-08):
>         -  A. Ballman: [[stdc::attr]] is incompatible with C++.  Better
>            fix [[attr]].
>
>         r8 (2025-09-04):
>         -  Fix standard attributes, instead of adding a new kind of
>            attributes.  This makes it compatible with C++, and also
>            significantly simplifies the proposal.
>         -  Retitle; this is now almost a Ghost.
>
>         r9 (2025-09-07):
>         -  Diagnose all unsupported attributes.  This is an Earthly
>            Demon.
>
>         r10 (2025-09-11):
>         -  Mention C++ p2552r3.
>
>         r11 (2025-09-25):
>         -  Remove paragraph.
>
>         r12 (2025-12-01):
>         -  tfix
>
> Description
>         Implementations are required to diagnose unrecognized standard
>         attributes.  This is required by the constraint in 6.7.13.2p2:
>
>                 The identifier in a standard attribute shall be one of:
>
>                         deprecated fallthrough maybe_unused nodiscard
>                         noreturn _Noreturn unsequenced reproducible
>
>         However, they're not required to diagnose about recognized but
>         unsupported standard attributes.  Or about unrecognized vendor
>         attributes.
>
>         The situation in an implementation that entirely ignores
>         attributes is such that for example, uses of the [[deprecated]]
>         attribute, where a programmer explicitly wants uses of some
>         function to be diagnosed, they are not diagnosed at all.  This
>         proposal would at least make the programmer aware that it won't
>         receive any diagnostics about uses of such attributed functions.
>
>         But this gets even worse when dealing with vendor attributes.
>         A program written for one compiler could be silently transformed
>         into a different program by another compiler which chooses to
>         ignore the attribute without diagnosing its use.  This is an
>         implicit Undefined Behavior that we need to remove.
>
>         Most existing implementations, if not all, already diagnose
>         unsupported attributes.  Let's make them all diagnose.  It
>         should be easy.  Just saying "Use of unsupported attributes" or
>         "attributes are not supported" would be fine, so it doesn't
>         impose any important implementation burden.  The implementation
>         doesn't even need to parse the attribute token/s.
>
>     C++
>         C++ has a related proposal, p2552r3.
>         <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2552r3.pdf>
>
>         It essentially proposes three rules:
>
>         -  The First Ignorability Rule.
>
>                 > Standard attributes cannot be syntactically ignored.
>
>                 This is essentially covered by this proposal too.  The
>                 added constraint, which makes use of unsupported
>                 attributes a constraint violation, and the removal of
>                 the ambiguous sentence about ignoring attributes,
>                 result in them being not syntactically accepted.
>
>                 The C++ proposal says that Clang mentioned
>
>                 > that mandating to check the syntax of standard
>                 > attributes would be an unacceptable implementation
>                 > burden in particular with regards to checking
>                 > appertainment;
>
>                 This is where this proposal differs from C++'s.  Under
>                 my proposal, implementations are free to continue
>                 ignoring the syntax within [[...]].  They don't need to
>                 parse the attribute, as long as they produce a
>                 diagnostic, which can be as simple as saying "Attributes
>                 are not supported by this implementation".  Such a
>                 diagnostic is enough to protect programmers from the
>                 danger of using code that is ignored by the
>                 implementation, while keeping implementation burden down
>                 to the bare minimum.  Under this proposal, [[...]] is
>                 essentially "token soup" (if the implementation decides
>                 so), as called by the C++ proposal.
>
>         -  The Second Ignorability Rule.
>
>                 Keep the status quo.  This is maintained by my proposal.
>                 That's guaranteed by n3550::6.7.13.2p3:
>
>                 > A strictly conforming program using a standard
>                 > attribute remains strictly conforming in the absence
>                 > of that attribute.
>
>                 That text is not changed by this proposal.
>
>         -  The Third Ignorability Rule.
>
>                 The C++ proposal has two approaches.  The first one is
>                 the most reasonable one, and is the one which is
>                 compatible with all of the existing wording of the
>                 standard.
>
>                 n3550 says this for attributes:
>
>                 > The __has_c_attribute conditional inclusion expression
>                 > (6.10.2) shall return the value 202311L when given
>                 > nodiscard as the pp-tokens operand if the
>                 > implementation supports the attribute.
>
>                 If an implementation reports such a value, it's telling
>                 the programmer that the implementation supports the
>                 attribute.  And the attribute was only allowed to be
>                 ignored if unsupported, so any other reading of the
>                 standard would be self-inconsistent.
>
>                 My proposal follows the same.  By removing the ambiguous
>                 sentence about ignoring unsupported attributes, but
>                 keeping the sentences about __has_c_attribute(), we keep
>                 this status quo.
>
>         So, my proposal seems to be consistent with p2552r3 regarding
>         rules 2 and 3, and seems to be preferable regarding rule 1, at
>         least according to Clang.
>
> Proposed wording
>         Based on N3550.
>
>     6.7.13.1  Attributes :: Introduction
>         @@ p2
>          Support for any of
>          the standard attributes
>          specified in this document
>          is implementation-defined and optional.
>          For an attribute token
>          (including an attribute prefixed token)
>          not specified in this document,
>          the behavior is implementation-defined.
>         -Any attribute token
>         -that is not supported by the implementation
>         -is ignored.
>
>     6.7.13.2  Attributes :: General
>         @@ Syntax, p1
>         -standard-attribute:
>         -       identifier
>
>         ## The above is moved into 6.7.13.2+1 "Standard attributes".
>
>         @@ Constraints, p2
>         -The identifier in a standard attribute
>         -shall be one of:
>         -       deprecated      maybe_unused    noreturn        unsequenced
>         -       fallthrough     nodiscard       _Noreturn       reproducible
>
>         ## The above is moved into 6.7.13.2+1 "Standard attributes".
>
>         @@ Constraints, new p2+1
>         +A program shall not use an attribute
>         +that is not supported by the implementation,
>         +except as an argument to
>         +the <b>__has_c_attribute</b> conditional inclusion expression.
>
>
>     6.7.13.3..6.7.13.8
>         ## Move these subsections to under 6.7.13.2+1 'Standard attributes'.
>
>     6.7.13  Attributes
>         @@
>         +6.7.13.2+1  Standard attributes
>         +
>         +Syntax
>         +1
>         +standard-attribute:
>         +       identifier
>         +
>         +Constraints
>         +2      The identifier in a standard attribute
>         +       shall be one of:
>         +               deprecated      maybe_unused    noreturn        
> unsequenced
>         +               fallthrough     nodiscard       _Noreturn       
> reproducible
>
>         ## The above is moved from 6.7.13.2p1,2
>
>         ## 6.7.13.3..6.7.13.8 are moved here as sub-clauses.
>
> --
> <https://www.alejandro-colomar.es>

Reply via email to