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]

Handling of extern inline in c99 mode


[ Moved from gcc-patches@ to gcc@. ]

Andrew Pinski <pinskia@gmail.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
> -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


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