CDeclaration vs Definition

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)

C
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

C
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 ;, no { } body

Has a { } body

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.

Calling an undeclared function is dangerous
In modern C (C99 and later), calling a function the compiler has not seen a declaration for is a hard error. In older compilers or with looser settings, it may only produce a warning and the compiler will *assume* a signature (historically, a function returning `int` with unspecified parameters). If that assumption does not match the real function, you get incorrect code generation, silently wrong values, or undefined behavior — a bug that can be very hard to track down. Always make sure a function is declared before you call it.
Seeing the Problem

Calling before declaring: a compiler error

C
#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

C
#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.

One definition, many declarations
A function must be *defined* exactly once across your entire program, but it can be *declared* many times (for example, once per file that includes its header) — as long as every declaration agrees on the signature.
Coming up
Next, we'll look closely at parameters and arguments — what goes in the parameter list of a declaration/definition, and what you actually pass when calling the function.