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>
