[ Moved from gcc-patches@ to [EMAIL PROTECTED] ] Andrew Pinski <[EMAIL PROTECTED]> writes:
> On Tue, 2006-10-31 at 21:34 -0800, Geoffrey Keating wrote: > > Here's the list of log (and therefore ChangeLog) entries. There is > > one change that I haven't merged yet, Caroline's pubtypes changes; > > that seems to need some work, I'll leave it for Caroline. > > Well, the following problem on any glibc target is now broken with > -std=c99: > > #include <stdio.h> > > int main(void) > { > printf("%d\n", 1); > return 0; > } We discussed this offline. The problem, as many people know, is that the tradition gcc definition of "extern inline" is incompatible with the C99 definition. The meanings are approximately reversed. Here is a review followed by a proposal. Review: In traditional gcc, "extern inline" means that the function should be inlined whereever it is used, and no function definition should be emitted. Moreover, it is permitted to provide both an "extern inline" and a normal definition, in which case the normal definition takes precedence. In traditional gcc, "inline" without "extern" or "static" means that the function should be compiled inline where the inline definition is seen, and the compiler should also emit a copy of the function body with an externally visible symbol, as though the declaration appeared without "inline". In C99, "extern inline" means that the function should be compiled inline where the inline definition is seen, and that the compiler should also emit a copy of the function body with an externally visible symbol. That is, C99 "extern inline" is equivalent to traditional gcc "inline". In C99, "inline" without "extern" or "static" means that the function should be compiled inline and that no externally visible function body should be emitted. That is, C99 "inline" is similar to traditional gcc "extern inline", although there is no equivalent ability to override the inline definition with a non-inline definition. 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. End of review. The proposal is due to Zack, except for where I've butchered 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. 2) Add a new warning, turned on by default, for all uses of "extern inline". The warning should say that the meaning of "extern inline" is different in c99 and gnu99, and that the default behaviour will be changing. Backport this warning to all open branches. Note that warnings are not issued for system header files, so this warning will not trigger on glibc in ordinary usage. 3) In c99 and gn99 mode, treat bare "inline" as specified by the C99 standard (including the specified behaviour if "inline" and "extern" appear in separate declarations). In gnu89 mode, issue a warning for bare "inline", saying that the behaviour will change in gnu99 mode. The rationale here is that uses of bare "inline" in the gnu89 sense are less common than uses of "extern inline". codesearch.google.com finds about 6000 uses of "extern line" in code written in C, but the search inline -static -extern -# lang:c file:\.c$ finds only 100 occurrences (I excluded .h files here because any normal inline declaration in a .h file in traditional gcc should be "extern inline" or "static inline", so most of those .h files are probably actually C++). 4) In gcc 4.4, change c99 and gnu99 to use the C99 mandated definition of "extern inline". Keep the warnings in gnu89 mode. 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. Comments? Ian