Name n3576 - Relax restrictions on standard attributes Principles - Uphold the character of the language. - Keep the language small and simple. - Codify existing practice to address evident deficiencies. Category Attributes Author Alejandro Colomar Cc: Joseph Myers Cc: Alex Celeste Cc: Martin Uecker History 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): - tfix. - wfix. - Rebase on n3550. Description Dialects have been using attributes for a long time to extend the language. Attributes have historically been important, and code wouldn't work without them. Some features being proposed for standardization would naturally be implemented as attributes, and the fact that standard attributes are not allowed to change the validity or semantics of a valid progra makes them artificially unsuitable, thus needing the invention of a new attribute-like mechanism. This is a workaround for a not-so-good standard attribute specification, and not something we really want. It is still useful to allow implementations to ignore attributes, but this shouldn't necessarily mean that the program is still valid and has the same meaning. Since scoped attributes (vendor::) are allowed to change validity and semantics of a program, let's add a standard set of scoped attrbiutes that are consistent with that, and let programmers use #if/#error/#endif or _Static_assert(3) with __has_c_attribute() to specify that the uses of an attribute in a program are meaningful. _Static_assert(__has_c_attribute(gnu::packed) || __has_c_attribute(stdc::packed)); #define PACKED [[gnu::packed, stdc::packed]] This would allow us to standardize existing vendor attributes as is, without an explosion of new keywords that don't fit well in any of the existing categories. Scoped attributes Since some people seem to want a set of annotations whose removal can't affect a valid program, let's keep them as unscoped attributes, and add a new set of standard attributes that are scoped under stdc::, which, like vendor attributes, are allowed to change validity and/or behavior of a program. We should then rename 'standard attributes' to 'attribute prefixless tokens'. And then 'standard attribute' would englobe both prefixless attributes and stdc:: attributes. Prior art Most (all?) vendors implement attributes, like [[gnu::packed]], which change the meaning of code, and thus can't be ignored. Users of these attributes need to use _Static_assert(3) to make sure the attribute is not ignored. It would be interesting to standardize [[gnu::packed]] as [[stdc::packed]], but current rules don't allow us to do that. Proposed wording Based on N3550. 6.2.1 Scopes of identifiers, type names, and compound literals @@ p1 An identifier can denote: - -- a standard attribute, + -- an attribute prefixless token, an attribute prefix, or an attribute name; -- an object; 6.2.3 Name spaces of identifiers @@ p1 - -- standard attributes + -- attribute prefixless tokens and attribute prefixes ... 6.2.7 Compatible type and composite type @@ p3 -- If one of the types has a standard attribute, the composite type also has that attribute. ## Keep p3 using standard attributes, since we want stdc:: ## attributes to compose in the same way. 6.4.3.1 Identifiers :: General @@ Semantics, p9 If a program defines a reserved identifier -or standard attribute token +or attribute prefixless token described in 6.7.13.2 as a macro name, or removes (with #undef) any macro definition of an identifier in the first group listed previously -or standard attribute token +or attribute prefixless token described in 6.7.13.2, the behavior is undefined. 6.7.13.1 Attributes :: Introduction @@ p1 Attributes specify additional information for various source constructs such as types, objects, identifiers, or blocks. They are identified by an attribute token, which can either be a attribute prefixed token -(for implementation-specific attributes) or -a standard attribute +an attribute prefixless token specified by an identifier -(for attributes specified in this document). +(only for attributes specified in this document). @@ New p after p1 +The attribute prefixed tokens +with prefix stdc:: +are called +the standard prefixed attributes. +These is reserved to +attributes specified in this document. @@ Another new p after p1 +The attribute prefixless tokens +and the standard prefixed attributes +are collectively called +the standard attributes. @@ p2 Support for any of -the standard attributes +the attribute prefixless tokens 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. -is ignored, +except for standard prefixed attributes. @@ New p _before_ p4 +In all aspects of the language, +an attribute prefix specified by this document +as stdc:: +and a prefix __stdc__ +shall behave the same +when used as an attribute prefix +except for the spelling. @@ p4 In all aspects of the language, -a standard attribute +an attribute name or attribute prefixless token specified by this document as an identifier attr and an identifier of the form __attr__ shall behave the same when used as an attribute token, except for the spelling. 175) ## In p5, keep standard attributes, since __has_c_attribute() ## should work for both in the same way. 6.7.13.2 Attributes :: General @@ Syntax, p1 attribute-token: - standard-attribute + attribute-prefixless-token attribute-prefixed-token -standard-attribute: +attribute-prefixless-token: identifier ## Add new subsection 6.7.13.2+1 section 'Prefixless attributes' ## after 'General'. Move p2 from General into this new section. @@ Constraints, p2; (move into 6.7.13.2+1 'Prefixless attributes') The identifier -in a standard attribute +in an attribute prefixless token shall be one of: @@ Semantics, p3 An attribute specifier that contains no attributes has no effect. The order in which attribute tokens appear in an attribute list is not significant. If a keyword (6.4.2) that satisfies the syntactic requirements of an identifier (6.4.3) is contained in an attribute token, it is considered an identifier. A strictly conforming program -using a standard attribute +using an attribute prefixless token remains strictly conforming in the absence of that attribute. 6.7.13.3..6.7.13.8 ## Move these subsections to under 6.7.13.2+1 'Prefixless ## attributes'. 6.7.13 Attributes ## Add new section after 6.7.13.2+1 ('Prefixless attributes'). @@ +6.7.13.2+2 Standard prefixed attributes + +Constraints +1 A program must not use a standard prefixed attribute + that is not supported by the implementation.