Date: Tue, 10 Feb 2026 17:52:17 +0100
On 10/02/2026 17:25, Barry Revzin wrote:
>
>
> On Tue, Feb 10, 2026, 10:13 AM David Brown via Std-Proposals
> <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>
> wrote:
>
>>
>> While that is all true, it defeats the point of attributes (at least
>> non-standard attributes) in the first place. After all, why support
>> [[gnu::cold]] or [[msvc::cold_func]] (if that existed) format when you
>> could have simply written :
>>
>> #if defined(__GNUC__)
>> # define COLD __attribute__((cold))
>> #elif defined(_MSC_VER)
>> # define COLD _declspec(cold_func)
>> #else
>> # define COLD
>> #endif
>>
>> COLD void f(void);
>>
>> Compiler-check conditional compilation and conditional macro
>> definitions
>> are horrible. Conditional compilation and macro definitions based on
>> feature checks are marginally less horrible, but only marginally so.
>> Both can be very useful, but you don't want to have to use them except
>> in rare and unusual cases. It is far better to be able to write :
>>
>> [[gnu::cold, msvc::cold_func]] void f(void);
>>
>> and skip the pre-processor stuff.
>>
>
> This right here immediately gets straight to the issue. The only
> remotely plausible argument for there being any value in ignoring
> attributes is precisely that: to be able to write code like that and
> skip the preprocessor stuff.
>
> The problem is, it comes with it the very big cost that the compiler of
> course has no way to differentiate between the cases where you might
> conceivably want it to ignore... and the cases where you just wrote the
> wrong thing by accident and it's a bug. Even in this case where you
> might think is easy, just ignore vendored attributes in a different
> namespace, what if I wrote mvsc::meow instead of msvc::meow?
>
> As I wrote in my blog
> (https://brevzin.github.io/c++/2025/03/25/attributes/
> <https://brevzin.github.io/c++/2025/03/25/attributes/>), a solution that
> would actually be useful here would be allow users to explicitly declare
> attributes they want "ignored" - which still isn't ignoring attributes
> (a design strategy that has clear negative value), simply explicitly
> declaring them to be no-ops. That would still require the preprocessor
> stuff, but only once per attribute, and the usage would have the good,
> macro-free syntax.
>
> Attributes are a great feature for adding new functionality without
> having to introduce new (uglier) keywords or grammar.
>
> Or, at least, they could be, if we just stop pre-emptively crippling
> them and pretending they're glorified comments.
>
> Barry
>
I liked that blog article - very informative and well-written,
presenting your arguments clearly. I agree with a great deal of it.
I do think that attributes should rarely be ignorable. (That is
especially when the implementation-defined behaviour of a particular
attribute could be "do nothing".) Unfortunately, that ship has sailed
in regard to the current attribute syntax. So something is needed to
say "I meant to write this attribute - it is not one of these old
ignorable ones". Pulling the ship back to harbour, so that [[attr]] and
[[comp::attr]] are not ignorable, would have to be done in a few rounds
so that we don't break existing code.
Thus my suggestion for a simple "never ignore" syntax is [[[attr]]] and
[[[comp::attr]]].
But I also think it is occasionally useful for a given usage to be
ignorable. And I think it is better to be clear about it there and
then, rather than hidden via a macro of the style you suggest:
#if __has_cpp_attribute(nodiscard)
# define LIB_NODISCARD [[nodiscard]]
#else
# define LIB_NODISCARD
#endif
My suggestion of [[(attr)]] and [[(comp::attr)]] puts the "may be
ignored" indication where it should be - at the point of usage. It is
also somewhat different from yours. While your method is "/must/ be
ignored", mine is "/may/ be ignored", and its ignorability is not based
on a single check. Perhaps you have an attribute that can only
reasonably be checked when some compiler flag is given, or when doing
link-time optimisation. I'd want to give the compiler the attribute,
even though I know that it might not always be able to do something
useful with it. (To be fair, all this depends somewhat on what is meant
by "ignoring" the attribute.)
I'm okay with conditional compilation where it is useful and the only
practical syntax, but I'd prefer to avoid it if there are better
alternatives. Macros are not evil, but they are not particularly nice.
David
>
>
> On Tue, Feb 10, 2026, 10:13 AM David Brown via Std-Proposals
> <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>
> wrote:
>
>>
>> While that is all true, it defeats the point of attributes (at least
>> non-standard attributes) in the first place. After all, why support
>> [[gnu::cold]] or [[msvc::cold_func]] (if that existed) format when you
>> could have simply written :
>>
>> #if defined(__GNUC__)
>> # define COLD __attribute__((cold))
>> #elif defined(_MSC_VER)
>> # define COLD _declspec(cold_func)
>> #else
>> # define COLD
>> #endif
>>
>> COLD void f(void);
>>
>> Compiler-check conditional compilation and conditional macro
>> definitions
>> are horrible. Conditional compilation and macro definitions based on
>> feature checks are marginally less horrible, but only marginally so.
>> Both can be very useful, but you don't want to have to use them except
>> in rare and unusual cases. It is far better to be able to write :
>>
>> [[gnu::cold, msvc::cold_func]] void f(void);
>>
>> and skip the pre-processor stuff.
>>
>
> This right here immediately gets straight to the issue. The only
> remotely plausible argument for there being any value in ignoring
> attributes is precisely that: to be able to write code like that and
> skip the preprocessor stuff.
>
> The problem is, it comes with it the very big cost that the compiler of
> course has no way to differentiate between the cases where you might
> conceivably want it to ignore... and the cases where you just wrote the
> wrong thing by accident and it's a bug. Even in this case where you
> might think is easy, just ignore vendored attributes in a different
> namespace, what if I wrote mvsc::meow instead of msvc::meow?
>
> As I wrote in my blog
> (https://brevzin.github.io/c++/2025/03/25/attributes/
> <https://brevzin.github.io/c++/2025/03/25/attributes/>), a solution that
> would actually be useful here would be allow users to explicitly declare
> attributes they want "ignored" - which still isn't ignoring attributes
> (a design strategy that has clear negative value), simply explicitly
> declaring them to be no-ops. That would still require the preprocessor
> stuff, but only once per attribute, and the usage would have the good,
> macro-free syntax.
>
> Attributes are a great feature for adding new functionality without
> having to introduce new (uglier) keywords or grammar.
>
> Or, at least, they could be, if we just stop pre-emptively crippling
> them and pretending they're glorified comments.
>
> Barry
>
I liked that blog article - very informative and well-written,
presenting your arguments clearly. I agree with a great deal of it.
I do think that attributes should rarely be ignorable. (That is
especially when the implementation-defined behaviour of a particular
attribute could be "do nothing".) Unfortunately, that ship has sailed
in regard to the current attribute syntax. So something is needed to
say "I meant to write this attribute - it is not one of these old
ignorable ones". Pulling the ship back to harbour, so that [[attr]] and
[[comp::attr]] are not ignorable, would have to be done in a few rounds
so that we don't break existing code.
Thus my suggestion for a simple "never ignore" syntax is [[[attr]]] and
[[[comp::attr]]].
But I also think it is occasionally useful for a given usage to be
ignorable. And I think it is better to be clear about it there and
then, rather than hidden via a macro of the style you suggest:
#if __has_cpp_attribute(nodiscard)
# define LIB_NODISCARD [[nodiscard]]
#else
# define LIB_NODISCARD
#endif
My suggestion of [[(attr)]] and [[(comp::attr)]] puts the "may be
ignored" indication where it should be - at the point of usage. It is
also somewhat different from yours. While your method is "/must/ be
ignored", mine is "/may/ be ignored", and its ignorability is not based
on a single check. Perhaps you have an attribute that can only
reasonably be checked when some compiler flag is given, or when doing
link-time optimisation. I'd want to give the compiler the attribute,
even though I know that it might not always be able to do something
useful with it. (To be fair, all this depends somewhat on what is meant
by "ignoring" the attribute.)
I'm okay with conditional compilation where it is useful and the only
practical syntax, but I'd prefer to avoid it if there are better
alternatives. Macros are not evil, but they are not particularly nice.
David
Received on 2026-02-10 16:52:22
