[Main]
Title=Prototypes and Old-Style Function Definitions

[Top]
GNU C extends ISO C to allow a function prototype to override a later
old-style non-prototype definition.  Consider the following example:
<PRE>/* Use prototypes unless the compiler is old-fashioned.  */
#ifdef __STDC__
#define P(x) x
#else
#define P(x) ()
#endif

/* Prototype function declaration.  */
int isroot P((uid_t));

/* Old-style function definition.  */
int
isroot (x)   /* ??? lossage here ??? */
     uid_t x;
{
  return x == 0;
}
</PRE>
Suppose the type <CODE>uid_t</CODE> happens to be <CODE><A HREF="$$INFOLINK(keywords/char)">char</A></CODE>.  ISO C does
not allow this example, because subword arguments in old-style
non-prototype definitions are promoted.  Therefore in this example the
function definition's argument is really an <CODE><A HREF="$$INFOLINK(keywords/int)">int</A></CODE>, which does not
match the prototype argument type of <CODE><A HREF="$$INFOLINK(keywords/char)">char</A></CODE>.
<BR><BR>
This restriction of ISO C makes it hard to write code that is portable
to traditional C compilers, because the programmer does not know
whether the <CODE>uid_t</CODE> type is <CODE>short</CODE>, <CODE>int</CODE>, or
<CODE>long</CODE>.  Therefore, in cases like these GNU C allows a prototype
to override a later old-style definition.  More precisely, in GNU C, a
function prototype argument type overrides the argument type specified
by a later old-style definition if the former type is the same as the
latter type before promotion.  Thus in GNU C the above example is
equivalent to the following:
<PRE>int isroot (uid_t);

int
isroot (uid_t x)
{
  return x == 0;
}
</PRE>
