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.
> >     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*.  It should have never been an
attribute, because, as you see, it doesn't attribute anything.

fallthrough is a jump statement misusing the syntax of an attribute.
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'.

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), 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.

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'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>

Attachment: signature.asc
Description: PGP signature

Reply via email to