Message ID | 7d28608ab5396836526b235526e0b757236cfc85.1461444595.git.zackw@panix.com |
---|---|
State | New |
Headers | show |
On 04/23/2016 01:05 AM, Zack Weinberg wrote:
> * misc/sys/cdefs.h: New utility macro __clang_has_extension.
I don't feel strongly about this, but the identifier looks like it's in
the Clang namespace. Perhaps use __glibc_clang_has_extension instead?
Florian
On Mon, Apr 25, 2016 at 3:22 AM, Florian Weimer <fweimer@redhat.com> wrote: > On 04/23/2016 01:05 AM, Zack Weinberg wrote: >> >> * misc/sys/cdefs.h: New utility macro __clang_has_extension. > > I don't feel strongly about this, but the identifier looks like it's in the > Clang namespace. Perhaps use __glibc_clang_has_extension instead? That's a good point, but I think the name __glibc_clang_has_extension is far too clunky to tolerate. Experimenting, clang treats __has_extension as an intrinsic *macro* -- for instance, #ifdef __has_extension is true. So maybe we could just do #ifndef __has_extension #define __has_extension(...) 0 #endif and that would be good enough? It seems consistent with the way sys/cdefs.h handles macro wrappers for GCC extensions. zw
On 04/25/2016 03:57 PM, Zack Weinberg wrote: > Experimenting, clang treats __has_extension as an intrinsic *macro* -- > for instance, #ifdef __has_extension is true. So maybe we could just do > > #ifndef __has_extension > #define __has_extension(...) 0 > #endif > > and that would be good enough? This will confuse application that checks for the presence of __has_extension. glibc should not provide compiler-defined macros coming from non-GNU compilers because it will be difficult to coordinate with these parties (it's sometimes even difficult with GCC). Florian
On 04/26/2016 06:48 AM, Florian Weimer wrote: > > This will confuse application that checks for the presence of > __has_extension. Yes. As an example of this sort of thing, GNU Emacs does this: #ifndef __has_attribute # define __has_attribute(a) __has_attribute_##a # define __has_attribute_alloc_size (4 < __GNUC__ + (3 <= __GNUC_MINOR__)) # define __has_attribute_cleanup (3 < __GNUC__ + (4 <= __GNUC_MINOR__)) ... and this would stop working if Glibc sys/cdefs.h defined __has_attribute(x) to be 0 when compiling with GCC. This specific example is about __has_attribute and not __has_extension, but the same idea applies to __has_extension.
I think this is a bad addition. I don't think we want miscellaneous header files to have Clang-specific #if checks. What we really want is for header files to do specific feature checks using some compiler-independent macros defined by <sys/cdefs.h>. This is also superior to the existing cases of headers using __GNUC_PREREQ as a proxy for specific feature tests. As Florian and Paul mentioned, new macros should avoid name space issues. Just use the prefix __glibc_ on any new macro. I think a generalized thing like __glibc_has_feature (foobar) would be fine. sys/cdefs.h can do a variety of macro magic things to map that to what works in Clang and to __GNUC_PREREQ for GCC. This is probably also the best way to enable distros that backport features to their compilers to update the corresponding conditionals easily, i.e. they can just patch sys/cdefs.h in their glibc package to change some of these macro definitions rather than dealing with the __GNUC_PREREQ mess throughout all the headers. You don't need to do the whole conversion for us, of course. But look at existing __GNUC_PREREQ tests and make sure that the scheme you come up with will extend readily to cover all those cases.
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h index 7fd4154..b31878b 100644 --- a/misc/sys/cdefs.h +++ b/misc/sys/cdefs.h @@ -77,7 +77,15 @@ #endif /* GCC. */ +/* Compilers that are not clang may object to + #if defined __clang__ && __has_extension (...) + even though they do not need to evaluate the right-hand side of the &&. */ +#ifdef __clang__ +# define __clang_has_extension(ext) __has_extension (ext) +#else +# define __clang_has_extension(ext) 0 +#endif + /* These two macros are not used in glibc anymore. They are kept here only because some other projects expect the macros to be defined. */ #define __P(args) args --