This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Handling of extern inline in c99 mode
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: Ian Lance Taylor <iant at google dot com>
- Cc: Andrew Pinski <pinskia at gmail dot com>, Geoffrey Keating <geoffk at apple dot com>, gcc at gcc dot gnu dot org
- Date: Wed, 1 Nov 2006 18:59:42 +0000 (UTC)
- Subject: Re: Handling of extern inline in c99 mode
- References: <2F4A331E-BB1F-4E0A-98E5-DF337E926B79@apple.com> <1162359635.19236.1.camel@celery.andrew.com> <m34ptj5f4g.fsf_-_@dhcp-172-18-118-195.corp.google.com>
On Wed, 1 Nov 2006, Ian Lance Taylor wrote:
> glibc uses "extern inline", and exploits the traditional gcc ability
> to override the "extern inline" function with a regular function. For
> example, the definition of tolower in <ctype.h> is:
>
> extern __inline int
> __NTH (tolower (int __c))
> {
> return __c >= -128 && __c < 256 ? (*__ctype_tolower_loc ())[__c] : __c;
> }
>
> but the defintion in tolower.c is:
>
> #define __ctype_tolower \
> ((int32_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_TOLOWER) + 128)
>
> int
> tolower (int c)
> {
> return c >= -128 && c < 256 ? __ctype_tolower[c] : c;
> }
>
> Note that these definitions are differently optimized for the
> different uses.
I would say the issue here is not so much the overriding but the
declaration of a standard function as inline at all. Because the function
is first declared without inline, and then later possibly defined with
inline, the later definition would cause the function "tolower" to be
exported from a source file using it.
> 1) Implement a function attribute which is the equivalent of "extern
> inline". Backport support for this attribute to all open branches.
> Try to persuade the glibc developers to use this feature instead of
> "extern inline" when it is available, by adjusting the handling of
> __USE_EXTERN_INLINES in features.h and elsewhere.
I'd rather simply fix glibc to work with C99 inline semantics. For the
above you might use
#define tolower(c) __tolower_inline(c)
static __inline __attribute__((__always_inline__)) int tolower_inline ...
and #undef tolower when defining the out of line function. That would
apply to all cases where a user-visible function in a header is currently
inlined directly; for a purely internal function in the header, we can
arrange for all declarations to use "inline" without "extern" when in C99
mode.
The glibc changes would be large but mechanical. The corresponding
fixincludes changes (necessary in any case) could probably disable most of
the extern inlines if glibc wasn't recent enough, but you might also
automate the above with fixincludes.
> This leaves open the question of when we want to change the default to
> gnu99, but I think it gives us a workable transition plan to get
> there, at least on this troublesome issue.
I propose the following list of things that need doing before a change of
default to gnu99:
* A -Wc89/-Wc90 option to warn for features different between C90 and C99.
(When building GCC we use -pedantic to cover this, but in gnu99 mode
-pedantic will no longer warn for features new in C99.)
* <stdint.h> implemented.
* Predefined macro names such as __STDC_ISO_10646__ properly defined for
whole translation unit in cooperation with libc.
* Standard pragmas.
* Complex numbers implementation audited against standard requirements.
* All uses of identifiers in the compiler audited for impact of extended
identifiers and extended identifiers implementation audited against list
in bug 9449 comment 21.
--
Joseph S. Myers
joseph@codesourcery.com