Date: Tue, 10 Feb 2026 10:25:14 -0600
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.
Barry
>
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.
Barry
>
Received on 2026-02-10 16:25:34
