Back in the olden days of really, really early C, there was no such thing as a prototype. Function argument lists came after the function’s parentheses, like this:
square(x)
int x;
{
int y = x * x;
return y;
}
These days, of course, the arguments go inside the parentheses:
square(int x)
{
int y = x * x;
return y;
}
Note the “missing” return type; C functions used to implicitly return int
, and it was only if you needed a different return type that you had to say what it was.
Function declarations had yet another set of rules. A function declaration in K&R C (the ancient version) had no arguments:
int square();
And function prototypes in ANSI C have a list of arguments:
int square(int x);
During the transition, people used wacky macros so they could compile both ways:
int square(PROTOTYPE(int x));
With
#define PROTOTYPE(s)
that would expand to the first version.
With
#define PROTOTYPE(s) s
it would expand to the second.
With regard to the “extra” parentheses in the code in the question, they’re needed when there is more than one argument in the argument list. Without them, the macro invocation has more than one argument, so won’t match a macro defined with just one argument:
PROTOTYPE(int x, int y) // error: too many arguments
PROTOTYPE((int x, int y)) // ok: only one argument (enclosed in parentheses)