[cfe-dev] [PATCH] New syntax and functionality for __has_attribute

dblaikie at gmail.com dblaikie at gmail.com
Sun Jan 12 10:22:19 PST 2014

> It's likely I didn't understand the question, so keep poking me until
> I get it right. :-)

Let's see how we go.

> > What I'm asking is, is there ever a case where a compile-time check is
> > required to decide which syntax to use? (where two compilers (including
> two
> > different versions of the same compiler) have support for the same
> attribute
> > but in disparate syntaxes?)
> >
> > The existence of an attribute with more than one, or less than all
> syntaxes
> > is not an issue - if in every compiler that implements the attribute it
> is
> > implemented in the same set of syntaxes, then there's no need to query
> which
> > syntax is valid, is there? It would be a universal constant.
> I may still be totally misunderstanding your concern, so I apologize
> if I'm being dense. But yes, there are cases where this comes up.
> Going back to my dllexport example since I think it's the most
> easily-recognizable. Here's a probably example of using this code in a
> cross-compiler code base:
> #if __has_attribute(dllexport)
>   #define DLLEXPORT __attribute__((dllexport))
> #else
>   #define DLLEXPORT
> #endif
> void func(void) DLLEXPORT;
> If you were to use this code today in clang, it would fail to compile.
>  __has_attribute(dllexport) will be replaced with 1, and so the
> resulting code would become: void func(void)
> __attribute__((dllexport));  However, we do not support dllexport with
> that syntax (we only support __declspec(dllexport)). So the code would
> look reasonable, but fail to compile.

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

> We could solve this by making __has_attribute *only* correspond to
> GNU-style attributes, but that's not how it works currently, and such
> a change could break existing code that currently works.

I don't think that's necessary. If each attribute has a documented list of
syntaxes/valid places, that should be sufficient.

> Not every compiler implements the same set of attributes, which is why
> __has_attribute exists in the first place.

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.

> Furthermore, not every
> compiler implements a given attribute with the same set of syntaxes
> (such as dllexport, which is implemented in gcc as both a GNU-style
> and an MS-style attribute, but it only an MS-style attribute in
> clang).

OK - this is what I'm interested in, but on further consideration I think
there's an even stronger requirement:

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.

Anyone trying to write portable code isn't going to write:

#if __has_attribute(__attribute__((dllexport)))
  #define DLLEXPORT __attribute__((dllexport))
#elif __has_attribute(declspec(dllexport))
  #define DLLEXPORT declspec(dllexport)
  #define DLLEXPORT

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

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).

> Even in situations where the compiler *does* implement all of
> the syntaxes consistently, it can be beneficial to know which syntax
> you are referring to within the context of __has_attribute because
> attribute placement is different between varying attribute syntaxes.

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.

> Does that clear things up, or am I still not understanding your concerns?

We're closer on the concerns, but I'm still not quite understanding the

> >> > Otherwise it just
> >> > seems an invariant of the attribute and not something that would need
> >> > compile time tests for because it won't vary by compilation
> >>
> >> I strongly disagree. Consider the dllexport example I had given.
> >> Supporting that is currently guess-work with __has_attribute because
> >> we only respond back that the attribute is known, but not a particular
> >> syntax.
> >
> >
> > Wouldn't it be documented somewhere? Why would it need to be queried
> > dynamically (at compile-time)? That would only be necessary if the
> attribute
> > was supported with different syntaxes in different compilers. Is that the
> > case?
> Yes, it is the case where the attribute is supported in different
> syntaxes in different compilers. That's why I keep picking on
> dllexport as an example. MSVC and clang support it as
> __declspec(dllexport) only, GCC supports it as __declspec(dllexport)
> or __attribute__((dllexport)).

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

- David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140112/24c524d0/attachment.html>

More information about the cfe-dev mailing list