Hi Paul, On Mon, Dec 15, 2025 at 10:44:19PM -0800, Paul Eggert wrote: > On 2025-12-15 14:17, Alejandro Colomar wrote: > > As a side note, the attribute should go before the type: > > Which is yet another reason to dislike the attribute syntax. That's one more > rule to remember, and I often forget it. Among other things I don't know > exactly why the C23 attribute must precede the return type (and I suspect > hardly any other C programmers do either).
The rule of thumb is:
- If an attribute is the first token in a declaration, it attributes
every declared identifier.
Example:
[[attr]] T f(void), g(void);
Both f() and g() are attributed.
- If an attribute is not the first thing in a declaration, it
attributes the thing immediately to its left.
Example:
T [[attr]] f(void);
The attribute is applied to the return type.
Example:
T f [[attr]] (void), g(void);
The attribute is applied to f(), but not g().
Example:
T f(void) [[attr]];
The attribute is applied to the function type 'T(void)'.
This second rule has an exception with struct/union/enum, where the
attribute goes between the keyword and the tag. I don't know why
they chose this weird placement, TBH.
I consider this placement much more logic and structured than GNU's
placement, which can only be described as "put it somewhere, and the
compiler will try to guess what you meant".
I agree it's not well documented anywhere. I should document this in
intro(3attr). I also agree that until someone tells you this rule of
thumb, it seems quite difficult to understand, but once someone told me
this (I forgot who it was), I find it relatively easy.
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
alx@devuan:~/tmp$ gcc -Wall -Wextra attr.c
attr.c:1:1: warning: ‘packed’ attribute ignored [-Wattributes]
1 | [[gnu::packed]] void f(void), g(void); // Attributed: f, g
| ^
attr.c:1:1: warning: ‘packed’ attribute ignored [-Wattributes]
attr.c:2:1: warning: ‘packed’ attribute ignored for type ‘void’
[-Wattributes]
2 | void [[gnu::packed]] h(void); // Attributed: void
| ^~~~
attr.c:3:1: warning: ‘packed’ attribute ignored [-Wattributes]
3 | void i [[gnu::packed]](void); // Attributed: i
| ^~~~
attr.c:4:1: warning: ‘packed’ attribute ignored for type ‘void(void)’
[-Wattributes]
4 | void j(void) [[gnu::packed]]; // Attributed: void(void)
| ^~~~
attr.c:6:1: warning: ‘pure’ attribute ignored [-Wattributes]
6 | [[pure]] enum a {A} v, vv; // Attributed: v, vv
| ^
attr.c:7:1: warning: ‘pure’ attribute ignored [-Wattributes]
7 | enum [[pure]] b {B} w; // Attributed: enum b
| ^~~~
attr.c:8:6: warning: ‘pure’ attribute ignored [-Wattributes]
8 | enum c [[pure]] {C} x; // Syntax error
| ^
attr.c:8:17: error: expected identifier or ‘(’ before ‘{’ token
8 | enum c [[pure]] {C} x; // Syntax error
| ^
attr.c:8:21: warning: data definition has no type or storage class
8 | enum c [[pure]] {C} x; // Syntax error
| ^
attr.c:8:21: error: type defaults to ‘int’ in declaration of ‘x’
[-Wimplicit-int]
attr.c:9:9: warning: ‘pure’ attribute ignored [-Wattributes]
9 | enum d {D} [[pure]] y; // I think this won't work.
| ^
attr.c:10:9: warning: ‘pure’ attribute ignored [-Wattributes]
10 | enum e {E} z [[pure]], zz; // Attributed: z
| ^
[...]
> > which compilers don't support [n] in function
> > parameters?
>
> Every C89-or-later compiler supports the syntax if n is an integer constant
> expression. If not, things get trickier; I don't offhand know which current
> compilers support it, but I vaguely recall that Microsoft compilers do not.
Thanks!
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
signature.asc
Description: PGP signature
