C++ Logo


Advanced search

Re: [SG10] Should the argument to __has_cpp_attribute be expanded by the preprocessor?

From: Richard Smith <richard_at_[hidden]>
Date: Mon, 9 Mar 2015 11:12:11 -0700
On Mon, Mar 9, 2015 at 6:33 AM, Jonathan Wakely <cxx_at_[hidden]> wrote:

> We couldn't wok out whether SD-6 intends this to work:
> #define D deprecated
> #if __has_cpp_attribute (D)
> #endif
> Currently GCC performs macro-expansion but Clang doesn't.

I don't have a preference here.

I think Clang inherits the "do not expand" behavior from its __has_feature
and __has_extension builtins, where avoiding expansion is an important
feature (some of our feature names are moderately likely to clash with
essentially unrelated macro names). It's also consistent with the treatment
of 'defined'.

Having the same expansion behavior for __has_cpp_attribute(D) and [[D]]
seems like it might be useful, but only marginally: you're already
restricted to only using this in a #if or #elif, so hard-coding the name of
the attribute doesn't seem like a huge hardship. I could just about see
value in something like this:

#if defined(__clang__)
#define FOO_ATTR_NS clang
#elif defined(__GNUC__)
#define FOO_ATTR_NS gnu
#elif /*...*/

#if __has_cpp_attribute(FOO_ATTR_NS::foo)
int main() {}

...but only if multiple vendors implement the same attribute as an
extension, but not under the same namespace prefix. For GCC attributes that
Clang emulates, it accepts [[gnu::attr]]; I'd expect other implementations
that attempt to be compatible with some other compiler to do the same, so
this should probably be a rare situation.

Received on 2015-03-09 19:12:12