Why do we use _PROTOTYPE e.g. _PROTOTYPE( void *memset, (void *_s, int _c, size_t _n) I saw it in MINIX3 source code
To accommodate both K&R and ANSI C function declaration styles. Take a look at Wikipedia article about C evolution.
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.
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();