This is the mail archive of the
mailing list for the GCC project.
Handling of extern inline in c99 mode
- From: Ian Lance Taylor <iant at google dot com>
- To: Andrew Pinski <pinskia at gmail dot com>, Geoffrey Keating <geoffk at apple dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: 01 Nov 2006 08:02:55 -0800
- Subject: Handling of extern inline in c99 mode
- References: <2F4A331E-BB1F-4E0A-98E5-DF337E926B79@apple.com> <firstname.lastname@example.org>
[ Moved from gcc-patches@ to gcc@. ]
Andrew Pinski <email@example.com> 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
> #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.
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
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)
tolower (int c)
return c >= -128 && c < 256 ? __ctype_tolower[c] : c;
Note that these definitions are differently optimized for the
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
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.