Function Prototypes
A function prototype is a declaration that tells the compiler a function's return type and the type of each parameter, without providing the function's body. Prototypes are how the compiler checks that every call to a function is consistent with how the function is actually defined.
Anatomy of a Prototype
A prototype
int add(int a, int b); // parameter names 'a' and 'b' are optional here int add(int, int); // this is equally valid — only the types matter
Parameter names in a prototype are purely documentation for whoever reads the code — the compiler only cares about the types and their order. Most style guides keep the names anyway, since int add(int, int); tells a reader far less than int add(int a, int b);.
Why Prototypes Matter
Without a prototype visible before a call, the compiler has nothing to check the call against. With one, it can catch real bugs the moment you compile, instead of letting them become runtime surprises.
A prototype catches a type mismatch
#include <stdio.h>
double area(double width, double height); // prototype
int main(void) {
// Compiler knows area() expects two doubles, and warns/errors here:
printf("%f\n", area("oops", 5));
return 0;
}
double area(double width, double height) {
return width * height;
}Forward Declaring Within a File
If you want to call a function before its definition appears later in the same file — often to keep main near the top for readability — place a prototype above the first use.
Forward declaration in a single file
#include <stdio.h>
int factorial(int n); // forward declaration
int main(void) {
printf("5! = %d\n", factorial(5)); // OK: prototype seen above
return 0;
}
int factorial(int n) { // definition comes after main
if (n <= 1) return 1;
return n * factorial(n - 1);
}void Means "No Arguments"
Writing void inside the parentheses explicitly tells the compiler the function takes no parameters at all.
No parameters, correctly declared
int getRandomNumber(void); // takes no arguments — enforced by the compiler
int main(void) {
int n = getRandomNumber();
// getRandomNumber(5); // compiler error: too many arguments
return 0;
}Form | Meaning | Recommended? |
|---|---|---|
| Takes exactly zero arguments (checked by compiler) | Yes |
| Old-style: unspecified arguments, no checking | No |
| Takes exactly two ints (checked by compiler) | Yes |
A prototype declares the return type and parameter types so the compiler can check calls.
Parameter names in a prototype are optional and purely documentation.
Use
(void)for a function that intentionally takes no arguments.Avoid empty
()parameter lists in new code — they disable type checking.