Because as the header block says, they didn't know if an ANSI compiler or K&R was going to be used, and this marco allows them to keep the parameters in an ANSI build, and throw them away in a K&R build.
00033 /* Keep everything for ANSI prototypes. */
00034 #define _PROTOTYPE(function, params) function params
verse
00045 /* Throw away the parameters for K&R prototypes. */
00046 #define _PROTOTYPE(function, params) function()
which means
00483 _PROTOTYPE( void _exit, (int _status) );
becomes under ANSI:
void _exit(int _status);
and under K&R:
void _exit();
The source code you linked to explains it:
00009 * If _ANSI ends up being defined, a macro
00010 *
00011 * _PROTOTYPE(function, params)
00012 *
00013 * is defined. This macro expands in different ways, generating either
00014 * ANSI Standard C prototypes or old-style K&R (Kernighan & Ritchie)
00015 * prototypes, as needed. Finally, some programs use _CONST, _VOIDSTAR etc
00016 * in such a way that they are portable over both ANSI and K&R compilers.
00017 * The appropriate macros are defined here.
Old-style K&R prototypes have the argument names first, then the types:
int foobar (x, y)
int x;
float *y;
{
/* code */
}
ANSI standard prototypes combine them both at the beginning:
int foobar (int x, float *y) {
/* code */
}
The _PROTOTYPE
macro creates an appropriate signature of either type depending on whether or not _ANSI
is defined. In this specific case, K&R signatures are used for function implementations, but the function declarations either include or omit their arguments depending on whether _ANSI
is defined.
It is worth noting that K&R-style declarations date from 1978 and most C code currently available will use modern ANSI style signatures. It is rare that you need to support both.