MC logo
The Development of Prototypes in C
[^] Functional Average III
------------------------------------------------------------------------------ The original C used a different syntax for declaring functions:
double fred();

double fred(a, b, c)
int a, b;
double c;
. . . 

In this original Kernigan and Ritchie C, parameter types are not part of the prototype, and are not checked against the call. That means that if you give the call fred(3.8, 22), the compiler won't complain that the arguments don't match the parameters, it will just compile the call and send what you say. What happens at run time will just be interesting. Declaring a function before its use is not required, and there's usually no particular reason to do so, since it really doesn't make much difference to how the call is checked or compiled.

When C++ was created, the authors felt this needed fixing. They created the prototype syntax with type names, and required that each function be declared before its first use in the code. That is, the compiler must see either the whole function or its prototype before it sees any call to the function. They also required that call arguments must agree with the function parameters. Later, the ANSI committee for C decided to add C++-style prototypes to C. Since they had to do this in such a way that existing code would not break, they could not simply decide that use of a function before its declaration is now illegal. Generally, the compiler enters information about a function when it first sees it, which can be either the function's declaration, a prototype, or a call. In the third case, it uses a default declaration corresponding to the pre-ANSI convention. When it encounters the function name again, it checks to see if this new sighting agrees with what it already knows, and complains if not. If it encounters an new-style declaration, it checks the given parameter types; if it encounters a pre-ANSI declaration, it checks only the return type.

The result of all this is, if you omit a prototype in C, the compiler will see your call first, enter the default properties for the function, then see your declaration. When it gets there, it will complain because the declaration does not agree with what it knows about the function. The message will typically say something about a disagreement, which seems a long way from “you forgot the prototype.”