<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
It's likely I didn't understand the question, so keep poking me until<br>
I get it right. :-)<br></blockquote><div><br></div><div>Let's see how we go.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> What I'm asking is, is there ever a case where a compile-time check is<br>
> required to decide which syntax to use? (where two compilers (including two<br>
> different versions of the same compiler) have support for the same attribute<br>
> but in disparate syntaxes?)<br>
><br>
> The existence of an attribute with more than one, or less than all syntaxes<br>
> is not an issue - if in every compiler that implements the attribute it is<br>
> implemented in the same set of syntaxes, then there's no need to query which<br>
> syntax is valid, is there? It would be a universal constant.<br>
<br>
I may still be totally misunderstanding your concern, so I apologize<br>
if I'm being dense. But yes, there are cases where this comes up.<br>
Going back to my dllexport example since I think it's the most<br>
easily-recognizable. Here's a probably example of using this code in a<br>
cross-compiler code base:<br>
<br>
#if __has_attribute(dllexport)<br>
#define DLLEXPORT __attribute__((dllexport))<br>
#else<br>
#define DLLEXPORT<br>
#endif<br>
<br>
void func(void) DLLEXPORT;<br>
<br>
If you were to use this code today in clang, it would fail to compile.<br>
__has_attribute(dllexport) will be replaced with 1, and so the<br>
resulting code would become: void func(void)<br>
__attribute__((dllexport)); However, we do not support dllexport with<br>
that syntax (we only support __declspec(dllexport)). So the code would<br>
look reasonable, but fail to compile.<br></blockquote><div><br></div><div>Sure - my argument here is this is /potentially/ just a lack of documentation. It's perhaps no more relevant than having a macro that tells you whether the return type is written "<here> func();" or "func() void" - it's an invariant of the language (or an invariant of the language extension, in the attribute case), not something that needs compile-time detection.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We could solve this by making __has_attribute *only* correspond to<br>
GNU-style attributes, but that's not how it works currently, and such<br>
a change could break existing code that currently works.<br></blockquote><div><br></div><div>I don't think that's necessary. If each attribute has a documented list of syntaxes/valid places, that should be sufficient.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Not every compiler implements the same set of attributes, which is why<br>
__has_attribute exists in the first place. </blockquote><div><br></div><div>Sure - I get that, I'm not questioning the motivation for __has_attribute as it stands today. I'm questioning the value of the ability to query for particular attribute syntax/spelling support that's being added here.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Furthermore, not every<br>
compiler implements a given attribute with the same set of syntaxes<br>
(such as dllexport, which is implemented in gcc as both a GNU-style<br>
and an MS-style attribute, but it only an MS-style attribute in<br>
clang).</blockquote><div><br></div><div>OK - this is what I'm interested in, but on further consideration I think there's an even stronger requirement:<br><br>For the has_feature per-syntax checking to be useful, we would have to be in a world in which two compilers (including different versions of the same compiler) support the same attribute in non-overlapping syntaxes. <br>
<br>Anyone trying to write portable code isn't going to write:<br><br>#if __has_attribute(__attribute__((dllexport)))<br> #define DLLEXPORT __attribute__((dllexport))<br>#elif __has_attribute(declspec(dllexport))<br>
#define DLLEXPORT declspec(dllexport)</div><div>#else<br> #define DLLEXPORT<br>#endif<br><br>They're just going to use the common subset that all compiler support (because generally these attributes have been implemented for compatibility with other compilers, yes?), thus just preferring the MS syntax in all cases.<br>
<br>One difference would be that having specific syntax feature detection would allow safe fallback - if someone had written the dllexport with GCC syntax using this new feature then on Clang it would've silently not exported (do people actually ever want that? For some attributes there's a logical fallback to just not use the attribute, dllexport/import doesn't seem to be one of those - but that's an aside) - whereas without the syntax-specific check you'd get an error and need to update the attribute syntax used in the DLLEXPORT macro to the one that's common between GCC and Clang (& whatever else).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Even in situations where the compiler *does* implement all of<br>
the syntaxes consistently, it can be beneficial to know which syntax<br>
you are referring to within the context of __has_attribute because<br>
attribute placement is different between varying attribute syntaxes.<br></blockquote><div><br></div><div>Again, this knowledge would be gained through explicit compiler documentation (as any other language feature or language extension) - not necessarily meriting a compile-time query system.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Does that clear things up, or am I still not understanding your concerns?<br></blockquote><div><br></div><div>We're closer on the concerns, but I'm still not quite understanding the justification.</div><div> </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
>> > Otherwise it just<br>
>> > seems an invariant of the attribute and not something that would need<br>
>> > compile time tests for because it won't vary by compilation<br>
>><br>
>> I strongly disagree. Consider the dllexport example I had given.<br>
>> Supporting that is currently guess-work with __has_attribute because<br>
>> we only respond back that the attribute is known, but not a particular<br>
>> syntax.<br>
><br>
><br>
> Wouldn't it be documented somewhere? Why would it need to be queried<br>
> dynamically (at compile-time)? That would only be necessary if the attribute<br>
> was supported with different syntaxes in different compilers. Is that the<br>
> case?<br>
<br>
Yes, it is the case where the attribute is supported in different<br>
syntaxes in different compilers. That's why I keep picking on<br>
dllexport as an example. MSVC and clang support it as<br>
__declspec(dllexport) only, GCC supports it as __declspec(dllexport)<br>
or __attribute__((dllexport)).<br></blockquote><div><br></div><div>Yep, it's a useful example (except I'm not sure it has a logical fallback, so I'm not sure how much people would actually conditionalize/feature-detect its use - and I assume GCC's support for multiple syntaxes is more or less by accident (I assume they support all attributes in all syntaxes just as a consequence of their implementation) & really the only one people /really/ would use would be the declspec version).<br>
<br>- David </div>