<div dir="ltr"><div dir="ltr">On Fri, Feb 28, 2020 at 11:23 AM James Y Knight via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On Fri, Feb 28, 2020 at 10:05 AM Aaron Ballman <<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">On Thu, Feb 27, 2020 at 6:04 PM James Y Knight <<a href="mailto:jyknight@google.com" target="_blank">jyknight@google.com</a>> wrote:<br>
><br>
> But, even with all that, I'm not sure why we shouldn't implement both __has_cpp_attribute AND __has_c_attribute in C++ mode?<br>
><br>
> The subset of C attributes which retain their C-defined semantics in C++ (which, hopefully, is all of them, but doesn't need to be) should return the appropriate C-standard date with which the (C++ mode) implementation is compatible. That is, in -std=c++11, we may have __has_cpp_attribute(deprecated) == 201309, while __has_c_attribute(deprecated) == 2020XXYY.<br>
<br>
If I'm understanding you properly, then I think that this leads to<br>
some strange (to me, at least) behavior. We have some attributes that<br>
are C only attributes, some attributes that are C++ only, but most of<br>
the attributes are supported in both C and C++ with the same<br>
semantics. For the attributes that are in both C and C++, what you<br>
suggest makes sense. For the attributes that exist only in one<br>
language, I'm less convinced. It would be weird for<br>
__has_c_attribute(gnu::transparent_union) (which is a C-only<br>
attribute) to report true in C and false in C++ because we do support<br>
that C attribute.</blockquote><div><br></div><div>That doesn't seem strange to me at all. it will correctly report that we do not support the C attribute <i>in the current compilation context</i>. These builtins should always be reporting whether the attribute feature is usable in the current compilation mode, not whether it might theoretically be usable with some other different set of compiler flags.</div><div><br></div><div>It'd be the same if we decide to only support C++74's [[frobnlezotz]] attribute when you compile code with the -std=c++74 flag. We should then return 0 from __has_cpp_attribute(frobnlezotz) when the code is compiled with -std=c++42.</div></div></div></blockquote><div><br></div><div>That's an argument to support only `__has_attribute`, right?  The compiler is never in both C and C++ modes simultaneously.  Furthermore, if it is in C mode, then it doesn't know what to return for `__has_cpp_attribute` because it doesn't know if it's "not in C++42 mode" or "not in C++74 mode." :)  Likewise, when in C++ mode, it doesn't know which C mode it's not-in.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div>Another thing that might seem weird is if we have a situation where C had standardized actually-incompatible behavior vs C++ for the same attribute name. [...]</div><div>That sort of incompatibility would be quite unfortunate, and I do hope we never need to do that. But if we do need to do it, I believe the above reporting of it makes sense and provides users with the ability to more-easily write C code that is portable to C++, even in the face of such unfortunate incompatibilities.</div></div></div></blockquote><div><br></div><div>This is a very strong reason to support only `__has_attribute`, and not prematurely bifurcate it into language-specific flags.  Remember, the first mover has the responsibility of setting precedent.  If Clang takes the lead in simplicity and user-friendliness, the Standards Committee will look at that and say, "Ah, vendors seem to be doing a single flag," and standardize that, and they'll know never to let the two languages' attributes get significantly out of sync because that would cause headaches for vendors.  On the other hand, if Clang goes out of its way to support "unfortunate incompatibilities," that will give license to the Standards Committee to <i>create and exploit</i> unfortunate incompatibilities.</div><div><br></div><div>I recommend that Clang should support `__has_attribute` as the fundamental syntactic primitive.  Code intended to be portable between C and C++ should use `__has_attribute`.</div><div>If WG21 happens to standardize the name `__has_cpp_attribute`, then Clang should add `__has_cpp_attribute` as a synonym for `__has_attribute`.</div><div><br></div><div>If you unwisely go the premature-bifurcation route and add __has_cpp_attribute and __has_c_attribute as non-synonyms, I encourage you to think about the other language front-ends, e.g. Objective-C. Will you add __has_objc_attribute, __has_objcxx_attribute, etc.?</div><div><br></div><div>–Arthur</div></div></div>