Categories
c c++ compiler-construction

Purpose of C/C++ Prototypes

I was reading wikipedia on C/C++ Prototype statements and I’m confused:

Wikipedia say: “By including the function prototype, you inform the compiler that the function “fac” takes one integer argument and you enable the compiler to catch these kinds of errors.”

and uses the below as an example:

#include <stdio.h>
/*
* If this prototype is provided, the compiler will catch the error
* in main(). If it is omitted, then the error will go unnoticed.
*/
int fac(int n); /* Prototype */
int main(void) { /* Calling function */
printf("%d\n", fac()); /* ERROR: fac is missing an argument! */
return 0;
}
int fac(int n) { /* Called function */
if (n == 0)
return 1;
else
return n * fac(n - 1);
}

But the function definition of the called function already includes all the information that the prototype tells the compiler, so why can’t the compiler deduce this information from the called function’s definition since they contain identical statements/information letter for letter?

What am I missing? Seems like extra work for no obvious gain.

Edit: Thanks guys. I assumed the compilers were multi-pass I guess. I’m spoiled to current languages like Python. It makes sense since it’s so old to need some kludges to do things accurately in a single pass. It seems more obvious to me now. Apparently it requires fairly intimate knowledge of how the compiler links and compiles.

Prototypes let you separate interface from implementation.

In your example, all of the code lives in one file, and you could just as easily have moved the fac() definition up where the prototype is currently and removed the prototype.

Real-world programs are composed of multiple .cpp files (aka compilation units), frequently compiled and linked into libraries before being linked into final executable form. For large scale projects of that nature, prototypes are collected into .h files (aka header files), where the header is included in other compilation units at compile time to alert the compiler to the existence and calling conventions of functionality in the library. In these cases, the function definition is not available to the compiler, so the prototypes (aka declarations) serve as a sort of contract defining the library’s capabilities and requirements.