<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Feb 28, 2020 at 10:05 AM Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid 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>
> That all makes sense -- especially the bits about the dates needing to be different.<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><br></div><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. Then in C++ compilation we'd need to report, for example:</div><div>  __has_c_attribute(deprecated) == 0 && __has_cpp_attribute(deprecated) == 201603</div><div>But, in C compilation we'd report:</div><div>  __has_c_attribute(deprecated) == 202001</div><div><br></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><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Similar for<br>
__has_cpp_attribute(clang::lifetimebound) (which is a C++-only<br>
attribute) to report true in C++ and false in C. Having the language<br>
in the name of the feature test macro is what makes this so awkward</blockquote><div><br></div><div>C should not support __has_cpp_attribute. C++ is overall backwards-compatible with C, which is why it's useful for C++ to support __has_c_attribute -- but the opposite is not the case.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> I'd hope/expect that whichever version of the C++ standard updates its baseline to C2x will adopt this feature "automatically", and if it doesn't, that it'll be included explicitly. But, ISTM we probably don't need to wait for that to occur in order to implement that behavior in clang?<br>
<br>
WG21 doesn't automatically incorporate the language parts of C, only<br>
the library parts, so this would require an explicit change to the<br>
standard. I would not be surprised if WG21 was just as unhappy about<br>
supporting __has_c_attribute as WG14 is about the idea of supporting<br>
__has_cpp_attribute for the same reasons.<br></blockquote><div><br></div><div>I believe they <i>should</i> not be unhappy to support this, when rebasing onto the C2x standard, because it will increase compatibility with C code, has extremely low cost, and makes sense.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Another possible option is to add __has_std_attribute with the<br>
behavior you describe, and possibly a pile of macros for the feature<br>
test dates. This negates the naming concern and retains the same<br>
semantics, but it comes at the expense of adding yet another way to<br>
feature test for attributes. Once we have field experience (and esp if<br>
we could convince GCC to adopt the same feature), hopefully both<br>
committees would have some appetite for standardizing it as an<br>
existing practice.<br></blockquote><div><br></div><div>This would be a significantly more complex solution than the above, and I see no advantage in it.</div><div><br></div></div></div>