On Thu, Mar 27, 2014 at 4:22 PM, Aaron Ballman <[email protected]> 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: >> --------- >> >> __has_attribute([[deprecated]]) >> __has_attribute(__attribute__((some_gnu_thing))) >> __has_attribute(__declspec(foobar)) >> __has_attribute([clsid]) >> >> 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 agree that Option B is preferable. > >> >> >> Testing for the presence of an attribute: __has_cpp_attribute >> >> [some introductory text] >> >> *Syntax* >> >> *has-attribute-expression:* >> __has_cpp_attribute ( *attribute-scoped-token* ) >> >> *Semantics* >> >> 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 >> p-number 0 otherwise. > > Do we want to consider any ideas for attribute versioning? For > instance, say there was a desire to allow [[noreturn]] on a lambda. > With this proposal, there's no way to differentiate between versions > of the [[noreturn]] attribute. We could use a feature test macro, but > that's what this proposal really is. > > We could support this by changing the pp-number replacement (0 means > not found, > 0 supported, but you could check the constant value to > see what version is supported).
Gently pinging this. Note: if it's a door we wish to leave open for the future, we could accomplish this with a minor wording modification to what we have already. Something like: The has-attribute-expression is replaced by <del>the pp-number 1</del><ins>a nonzero pp-number</ins> 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 agree that this paragraph can go. > >> >> *Example* >> >> 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 >> #endif > > ~Aaron ~Aaron _______________________________________________ Features mailing list [email protected] http://www.open-std.org/mailman/listinfo/features
