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 [EMAIL PROTECTED]