Date: Tue, 10 Feb 2026 11:37:44 -0500
On Tue, Feb 10, 2026 at 11:25 AM Barry Revzin via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> On Tue, Feb 10, 2026, 10:13 AM David Brown via Std-Proposals <std-proposals_at_[hidden]> wrote:
>> On 10/02/2026 16:21, Alejandro Colomar wrote:
>> > Hi David,
>> >
>> > On 2026-02-10T15:47:12+0100, David Brown wrote:
>> > [...]
>> >>>> [[comp::attr]]
>> >>>> Ignorable or non-ignorable according to the implementation (with the
>> >>>> recommendation that it is ignorable by default but that the compiler provide
>> >>>> a flag to make it non-ignorable).
>> >>>>
>> >>>> [[[comp::attr]]]
>> >>>> Non-ignorable. If a compiler cannot support this in the manner intended by
>> >>>> the "comp" compiler, it is a fatal error.
>> >>>>
>> >>>> [[(comp::attr)]]
>> >>>> Ignorable. Compilers are encouraged to provide a warning if they are the
>> >>>> owner of the "comp" namespace and do not recognise "attr".
>> >>>>
>> >>>> [[[comp1::attr1 || comp2::attr2 || ... ]]]
>> >>>> Non-ignorable. Compilers must support and apply one of these attributes,
>> >>>> but may choose which. If they cannot support any, it is a fatal error. For
>> >>>> example, [[[gnu::always_inline || msvc::forceinline]]]
>> >>>>
>> >>
>> >> You did not comment on this syntax, which I think is the most significant
>> >> new idea in my post. Do you like this idea, or do you have a better
>> >> alternative?
>> >
>> > That feature exists:
>> >
>> > #if __has_c_attribute(gnu::packed)
>> > # define PACKED gnu::packed
>> > #else if __has_c_attribute(foo::packed)
>> > # define PACKED foo::packed
>> > #else
>> > # error "No support for a packed attribute"
>> > #endif
>> >
>> > [[PACKED]] void f(void);
>> >
>> > I agree that || would be nice for this. I'd make it
>> >
>> > [[gnu::packed || foo::packed]]
>> >
>> > without a third '['
>> >
>>
>> (The third [ was for consistency with user indication that the attribute
>> should not be ignorable, but that's an orthogonal point.)
>>
>> >>
>> >>>> [[(comp1::attr1 || comp2::attr2 || ... )]]
>> >>>> The compiler can apply its choice of one of these attributes, but can ignore
>> >>>> them all.
>> >>>
>> >>> I think it's a bad idea to allow programmers to decide about the
>> >>> ignorability of language features. Ignorability of a feature should be
>> >>> part of the feature itself. What would it mean to do
>> >>>
>> >>> [[(gnu::packed)]]
>> >>>
>> >>> ? That's an ABI-breaking attribute, and ignoring it will result in
>> >>> bugs.
>> >>>
>> >>
>> >> We can't legislate against programmers doing something stupid! And we
>> >> certainly should not limit their abilities to make useful choices just
>> >> because some people might do something silly - at least not when it requires
>> >> an active choice such as this syntax requires. We should of course try to
>> >> reduce the risk of accidental mistakes (which is a big reason, IMHO, that
>> >> making "[[no_discard]]" ignorable is a terrible mistake - an accidental
>> >> misspelling of a language feature should result in an error message, not be
>> >> quietly discarded).
>> >>
>> >> But I think it would be fine for both the C++ standard and compiler
>> >> documentation for namespace attributes to say that certain attributes cannot
>> >> be ignored. If that applied to "gnu::packed", then "[[(gnu::packed)]]"
>> >> would be an error. But programmers should be allowed to mark an attribute
>> >> like "gnu::cold" as ignorable because it does not affect the semantics of
>> >> the program in any way.
>> >>
>> >>> I prefer keeping all vendor attributes non-ignorable, and close the door
>> >>> to ignorable vendor attributes. Then, if we want standard non-ignorable
>> >>> ones, let's just specify a standard "vendor"; that could be the empty
>> >>> prefix ::, or maybe std::.
>> >>>
>> >>
>> >> There are lots of vendor attributes that can be used today, and that would
>> >> be safe to ignore. I prefer to say that if an attribute is not ignorable
>> >> (either because the user has used [[[ ]]], or because the it is documented
>> >> as never ignorable) then it cannot be ignored by /any/ compiler. That
>> >> requirement puts a lot of pressure on compiler implementations, and I think
>> >> it is best to relieve that pressure by allowing attributes to be ignorable
>> >> when the user knows that is safe.
>> >
>> > That feature exists:
>> >
>> > #if __has_c_attribute(gnu::cold)
>> > # define COLD gnu::cold
>> > #else
>> > # define COLD
>> > #endif
>> >
>> > [[COLD]] void f(void);
>> >
>> > I don't see a need for a new spelling.
>> > I don't see a need to ignorable attributes.
>> >
>> >
>> > Cheers,
>> > Alex
>> >
>>
>> 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/), 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.
Why [[do]] we want [[to read]] code [[that]] looks [[like this]]? Why
is this a good thing for the language?
Attribute syntax is very eye-poking and makes code harder to read. Why
do we want to proliferate this everywhere? If we need a way to make
new keywords without impacting code, then we should add that as core
functionality.
People often talk about how the `co_await` and `co_return` keywords
look bad. Seing `[[await]]` and `[[return]]` wouldn't be any better.
Not only are they one keystroke longer, they poke you in the eye in a
way that just text with underscores does not.
Attributes are only a "great feature for adding new functionality" if
we ignore how they make the code look. I wasn't there for any of the
conversations for attribute syntax, but wasn't one of the agreements
made with the syntax that it *not* be used as a keyword replacement?
Which is why it wasn't used for alignas, override, and final?
This feels a bit like a deal was worked out that people are now trying
to renege on because it's convenient to do so.
<std-proposals_at_[hidden]> wrote:
> On Tue, Feb 10, 2026, 10:13 AM David Brown via Std-Proposals <std-proposals_at_[hidden]> wrote:
>> On 10/02/2026 16:21, Alejandro Colomar wrote:
>> > Hi David,
>> >
>> > On 2026-02-10T15:47:12+0100, David Brown wrote:
>> > [...]
>> >>>> [[comp::attr]]
>> >>>> Ignorable or non-ignorable according to the implementation (with the
>> >>>> recommendation that it is ignorable by default but that the compiler provide
>> >>>> a flag to make it non-ignorable).
>> >>>>
>> >>>> [[[comp::attr]]]
>> >>>> Non-ignorable. If a compiler cannot support this in the manner intended by
>> >>>> the "comp" compiler, it is a fatal error.
>> >>>>
>> >>>> [[(comp::attr)]]
>> >>>> Ignorable. Compilers are encouraged to provide a warning if they are the
>> >>>> owner of the "comp" namespace and do not recognise "attr".
>> >>>>
>> >>>> [[[comp1::attr1 || comp2::attr2 || ... ]]]
>> >>>> Non-ignorable. Compilers must support and apply one of these attributes,
>> >>>> but may choose which. If they cannot support any, it is a fatal error. For
>> >>>> example, [[[gnu::always_inline || msvc::forceinline]]]
>> >>>>
>> >>
>> >> You did not comment on this syntax, which I think is the most significant
>> >> new idea in my post. Do you like this idea, or do you have a better
>> >> alternative?
>> >
>> > That feature exists:
>> >
>> > #if __has_c_attribute(gnu::packed)
>> > # define PACKED gnu::packed
>> > #else if __has_c_attribute(foo::packed)
>> > # define PACKED foo::packed
>> > #else
>> > # error "No support for a packed attribute"
>> > #endif
>> >
>> > [[PACKED]] void f(void);
>> >
>> > I agree that || would be nice for this. I'd make it
>> >
>> > [[gnu::packed || foo::packed]]
>> >
>> > without a third '['
>> >
>>
>> (The third [ was for consistency with user indication that the attribute
>> should not be ignorable, but that's an orthogonal point.)
>>
>> >>
>> >>>> [[(comp1::attr1 || comp2::attr2 || ... )]]
>> >>>> The compiler can apply its choice of one of these attributes, but can ignore
>> >>>> them all.
>> >>>
>> >>> I think it's a bad idea to allow programmers to decide about the
>> >>> ignorability of language features. Ignorability of a feature should be
>> >>> part of the feature itself. What would it mean to do
>> >>>
>> >>> [[(gnu::packed)]]
>> >>>
>> >>> ? That's an ABI-breaking attribute, and ignoring it will result in
>> >>> bugs.
>> >>>
>> >>
>> >> We can't legislate against programmers doing something stupid! And we
>> >> certainly should not limit their abilities to make useful choices just
>> >> because some people might do something silly - at least not when it requires
>> >> an active choice such as this syntax requires. We should of course try to
>> >> reduce the risk of accidental mistakes (which is a big reason, IMHO, that
>> >> making "[[no_discard]]" ignorable is a terrible mistake - an accidental
>> >> misspelling of a language feature should result in an error message, not be
>> >> quietly discarded).
>> >>
>> >> But I think it would be fine for both the C++ standard and compiler
>> >> documentation for namespace attributes to say that certain attributes cannot
>> >> be ignored. If that applied to "gnu::packed", then "[[(gnu::packed)]]"
>> >> would be an error. But programmers should be allowed to mark an attribute
>> >> like "gnu::cold" as ignorable because it does not affect the semantics of
>> >> the program in any way.
>> >>
>> >>> I prefer keeping all vendor attributes non-ignorable, and close the door
>> >>> to ignorable vendor attributes. Then, if we want standard non-ignorable
>> >>> ones, let's just specify a standard "vendor"; that could be the empty
>> >>> prefix ::, or maybe std::.
>> >>>
>> >>
>> >> There are lots of vendor attributes that can be used today, and that would
>> >> be safe to ignore. I prefer to say that if an attribute is not ignorable
>> >> (either because the user has used [[[ ]]], or because the it is documented
>> >> as never ignorable) then it cannot be ignored by /any/ compiler. That
>> >> requirement puts a lot of pressure on compiler implementations, and I think
>> >> it is best to relieve that pressure by allowing attributes to be ignorable
>> >> when the user knows that is safe.
>> >
>> > That feature exists:
>> >
>> > #if __has_c_attribute(gnu::cold)
>> > # define COLD gnu::cold
>> > #else
>> > # define COLD
>> > #endif
>> >
>> > [[COLD]] void f(void);
>> >
>> > I don't see a need for a new spelling.
>> > I don't see a need to ignorable attributes.
>> >
>> >
>> > Cheers,
>> > Alex
>> >
>>
>> 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/), 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.
Why [[do]] we want [[to read]] code [[that]] looks [[like this]]? Why
is this a good thing for the language?
Attribute syntax is very eye-poking and makes code harder to read. Why
do we want to proliferate this everywhere? If we need a way to make
new keywords without impacting code, then we should add that as core
functionality.
People often talk about how the `co_await` and `co_return` keywords
look bad. Seing `[[await]]` and `[[return]]` wouldn't be any better.
Not only are they one keystroke longer, they poke you in the eye in a
way that just text with underscores does not.
Attributes are only a "great feature for adding new functionality" if
we ignore how they make the code look. I wasn't there for any of the
conversations for attribute syntax, but wasn't one of the agreements
made with the syntax that it *not* be used as a keyword replacement?
Which is why it wasn't used for alignas, override, and final?
This feels a bit like a deal was worked out that people are now trying
to renege on because it's convenient to do so.
Received on 2026-02-10 16:37:58
