Declaration vs Definition
C makes a strict distinction between declaring a function and defining it. Understanding this distinction is essential once your programs grow beyond a single file, and it explains a class of compiler errors and warnings that confuse many beginners.
Declaration: "This Function Exists"
A function declaration (often called a prototype) tells the compiler that a function with a given name, return type, and parameter types exists somewhere — without providing its body. It is a promise: "trust me, this function is defined elsewhere."
A function declaration (prototype)
int add(int a, int b); // declaration: ends with a semicolon, no body
Definition: "Here Is How It Works"
A function definition provides the actual body — the statements that run when the function is called. A definition also counts as a declaration, since it tells the compiler everything the declaration would.
A function definition
int add(int a, int b) { // definition: has a body
return a + b;
}Declaration | Definition |
|---|---|
Announces a function's signature | Provides the function's implementation |
Ends with a | Has a |
Can appear many times across files | Should appear exactly once in the whole program |
Lets you call the function before its body is written | Is what actually gets compiled into machine code |
Why C Requires This
C compilers traditionally read a source file from top to bottom in a single pass. When the compiler sees a function call, it needs to already know the function's return type and parameter types so it can generate correct code — for example, to know how many bytes to reserve for the return value, or whether an argument needs to be converted before being passed. A declaration gives the compiler that information ahead of time, which is why C requires a function to be declared (or defined) before it is used.
Seeing the Problem
Calling before declaring: a compiler error
#include <stdio.h>
int main(void) {
int result = add(2, 3); // error: 'add' is not declared here
printf("%d\n", result);
return 0;
}
int add(int a, int b) { // defined after main, but never declared before use
return a + b;
}There are two ways to fix this: move the definition of add above main, or add a declaration (prototype) above main and keep the definition wherever you like.
Fixed with a forward declaration
#include <stdio.h>
int add(int a, int b); // forward declaration
int main(void) {
int result = add(2, 3); // OK: compiler already knows add's signature
printf("%d\n", result);
return 0;
}
int add(int a, int b) { // definition can stay down here
return a + b;
}Header Files: A Preview
In real, multi-file C programs, the typical pattern is to put function declarations in a header file (.h) and function definitions in a corresponding source file (.c). Any other file that wants to use the function simply #includes the header, which gives the compiler the declarations it needs without duplicating the implementation. You will see this pattern in depth once you get to multi-file projects, but it is worth recognizing now: declarations and definitions living in different files is completely normal and is, in fact, the standard way C code is organized.