Zero-parameter K&R definitions specify that the function has no
parameters, but they are still not prototypes, so calling the function
with the wrong number of parameters is just a warning, not an error.
The C11 standard doesn't seem to directly define what a prototype is,
but it can be inferred from 6.9.1p7: "If the declarator includes a
parameter type list, the list also specifies the types of all the
parameters; such a declarator also serves as a function prototype
for later calls to the same function in the same translation unit."
This refers to 6.7.6.3p5: "If, in the declaration “T D1”, D1 has
the form
D(parameter-type-list)
or
D(identifier-list_opt)
[...]". Later in 6.11.7 it also refers only to the parameter-type-list
variant as prototype: "The use of function definitions with separate
parameter identifier and declaration lists (not prototype-format
parameter type and identifier declarators) is an obsolescent feature."
We already correctly treat an empty parameter list as non-prototype
declaration, so we can just take that information.
GCC also warns about this with -Wstrict-prototypes.
This shouldn't affect C++, because there all FunctionType's are
FunctionProtoTypes. I added a simple test for that.
I'd like a few more test cases:
// Test that a non-prototyped definition with no preceding prototype whines about lacking a preceding prototype void fooN() {} // expected-warning {{this old-style function definition is not preceded by a prototype}} // Test that an existing declaration with no prototype still warns that a corresponding definition with a type list is still not preceded by a prototype. void fooN1(); // expected-warning {{this function declaration is not a prototype}} void fooN1(void) {} // expected-warning {{this old-style function definition is not preceded by a prototype}}