On Mar 25, 2014, at 6:18 PM, Richard Smith <richard@metafoo.co.uk> wrote:

Last Monday we discussed the idea of adding an extensible mechanism to detect the presence of an attribute to SG10's recommendations, based on Clang's __has_attribute feature. Two important observations:

1) Implementations have attribute syntaxes other than C++ attributes (both for historical reasons and as an ongoing concern to support attributes in C), and
2) We need a mechanism to determine whether the attribute-detection feature is available.

Point (1) implies that we should not reserve the global name __has_attribute for *only* C++ attributes, so we considered the idea of a macro that takes the syntactic form of the attribute as an argument, leading us to:

Option A:


The natural way to address (2) with this model is to use a preprocessor defined(__has_attribute) check, matching our recommendation for __has_include. However, this presents a problem: that check will succeed for existing versions of Clang, but existing versions of Clang do not support an attribute-syntax argument to __has_attribute (only the name of a GNU __attribute__).

So, Option A would need to use either a feature-test macro (maybe __cpp_has_attribute), or a different macro name (maybe __has_attribute_syntax), in order to provide a way to portably check for the feature.

Option B:

A simpler approach would be to acknowledge point (1) in the macro name, giving:

  __has_cpp_attribute ( attribute-token )

Programs would test for the existence of this feature in the preprocessor with defined(__has_cpp_attribute), consistent with how they would check for __has_include. Vendors could choose to augment this with __has_gnu_attribute, __has_declspec_attribute, ... for the other syntaxes.

At this point, I think Option B is superior to Option A. Therefore, my first draft of a suggested addition to our recommendations is the following:

I am also in favor of option B.

Testing for the presence of an attribute: __has_cpp_attribute

[some introductory text]


    __has_cpp_attribute ( attribute-scoped-token )


A has-attribute-expression shall appear only in the controlling constant expression of a #if or #elif directive ([cpp.cond] 16.1). The has-attribute-expression is replaced by the pp-number 1 if the implementation supports an attribute with the specified name, and by the pp-number 0 otherwise.

The #ifdef and #ifndef directives, and the defined conditional inclusion operator, shall treat __has_cpp_attribute as if it were the name of a defined macro. The identifier __has_cpp_attribute shall not appear in any context not mentioned in this section.

An implementation should only claim to support an attribute-token with no attribute-namespace if it follows the behavior specified by a draft of the C++ standard or of a technical specification produced by ISO/IEC JTC1/SC22/WG21. An implementation should only claim to support an attribute-token with an attribute-namespace if it follows the behavior specified by the vendor identified by the attribute-namespace.

[OPEN QUESTION: Do we want to provide recommendations like this last paragraph at all? If so, should we list the currently-know attribute-namespaces? Having a centralized list of them is useful, and this seems like a good place to maintain that list. Would it be in-scope for the features SG to maintain a list of the known vendor extension attributes?]

I don't think the last paragraph is needed, not that I'd object if someone really wanted it.

I think the purpose of __has_cpp_attribute(name) is to indicate that [[name ...]] can be used as an attribute.   I don't think we need to specify things further than that.

I don't think maintaining a list of known vendor extension attributes is in the charter of SG10.   If one were maintained, would it be just the names, the names and the syntax, or the names, syntax, and semantics?



This demonstrates a way to use the attribute [[deprecated]] only if it is available.

#ifdef __has_cpp_attribute
#  if __has_cpp_attribute(deprecated)
#    define ATTR_DEPRECATED(msg) [[deprecated(msg)]]
#  endif
Features mailing list