This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Handling of extern inline in c99 mode


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]