https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796

--- Comment #10 from Aaron Ballman <aaron at aaronballman dot com> ---
One other reason for the Clang behavior that may be worth mentioning is that
this helps users who wish to migrate away from `__attribute__` and towards
`[[]]`. Many (most?) uses of attributes end up behind a macro, so the user may
not even be aware which syntax is being used. Consider this contrived example:
```
// LibraryHeader.h
#if SOMETHING
#define FOO_ATTR __attribute__((foo))
#define BAR_ATTR __attribute__((bar))
#define BAZ_ATTR [[lib::baz]]
#elif SOMETHING_ELSE
...
#else
#define FOO_ATTR
#define BAR_ATTR
#define BAZ_ATTR
#endif

// UserCode.c
FOO_ATTR BAR_ATTR void func(void) { ... }
```
The user reading UserCode.c has no idea what attribute syntax is being used,
nor do they probably care all that much.

Under a strict parsing model, trying to add `BAZ_ATTR` to the declaration of
`func()` requires the user to be very aware of exactly what each macro expands
to, otherwise they might get the order wrong.

With a relaxed parsing model, the user doesn't have to care. Additionally, the
library header can migrate `BAR_ATTR` to `[[gnu::bar]]` syntax without also
migrating `FOO_ATTR` at the same time with less fear of breaking downstream
users due to attribute ordering, so this allows for gradual migration to a
newer syntax. (It's not "no fear" because `[[]]` has strict appertainment
rules, so it's possible for some attributes to break user code when migrating
from `__attribute__` to `[[]]` due to differences in appertainment.)

Reply via email to