Why Functions Exist
A function is a named block of code you can run on demand by calling it. Instead of repeating the same logic in several places, you write it once, give it a name, and call that name wherever you need it. This keeps programs shorter, easier to read, and easier to fix - change the logic in one spot and every caller gets the update.
You have already been calling one function this whole time: main. It is the entry point every C++ program starts from. Now you will write your own. The loops you saw earlier, like the range-based for, often live inside functions so you can reuse a whole piece of logic by name.
Anatomy of a Function
Every function has four parts: a return type, a name, a parameter list in parentheses, and a body in braces.
int add(int a, int b) { // return type | name | parameters
return a + b; // body
}
intis the return type - the kind of value the function hands back.addis the name you use to call it.(int a, int b)are the parameters - inputs the caller supplies.- The braces hold the body, the code that runs when you call it.
Here it is in a complete program. Defining the function above main means main can see it when it calls.
The call add(2, 3) runs the function with a = 2 and b = 3, and the whole expression becomes the returned value. You can store it in a variable or use it directly inside another expression, like the second cout line does.
Returning a Value
The return statement does two things: it hands a value back to the caller, and it immediately ends the function. Any code after a return that runs does not execute - control jumps straight back to where the function was called.
The returned value's type must match (or convert to) the declared return type. A function declared int should return an int; returning nothing, or falling off the end without a return, is a bug for any non-void function.
Void Functions
Not every function produces a value. When a function just does something - prints output, updates state - its return type is void. A void function can use a bare return; to exit early, or simply run to the closing brace.
Trying to use the result of a void function - int x = greet("Ada"); - is a compile error, because there is no value to assign. A common mistake is writing return someValue; inside a void function; the compiler rejects that too.
Declarations vs. Definitions
C++ reads a file top to bottom, so by default a function must appear before the code that calls it. When that ordering is awkward, you split the function into a declaration (also called a prototype) and a definition.
A declaration states the function's signature and ends with a semicolon - no body. It promises the compiler "this function exists; here is how to call it." The full definition can then come later, even after main.
Without the prototype on line 4, the compiler would hit square(5) inside main before it has ever seen square, and the build would fail. Prototypes are also how header files let many source files share the same functions. Note the parameter names in a declaration are optional - int square(int); works just as well; only the types matter to the compiler.
Common Mistakes
A few traps catch beginners again and again:
- Calling before declaring. If you get an "
addwas not declared in this scope" error, the function is defined below its first call and has no prototype. Move the definition up or add a prototype. - Forgetting to return. Reaching the end of a non-
voidfunction without areturnis undefined behavior - the caller receives garbage. Compile with warnings on (-Wall) and the compiler will flag it. - Defining vs. calling. A definition has a body in braces and no trailing semicolon. A declaration has a semicolon and no body. Mixing them up - like putting a semicolon right after the parameter list of a function you meant to define - produces confusing errors.
- Ignoring the return value.
add(2, 3);on its own line compiles, but the computed sum is silently thrown away. Make sure you actually use what a function returns.
// Looks like a definition, but the stray ; turns it into a
// declaration followed by a leftover block - a frequent typo:
int triple(int n); // <- this ; ends the statement
{
return n * 3; // n is undefined here; this block is now orphaned
}
Next: Function Parameters
You have seen functions take inputs through their parameter list, but there is much more to it. The next page digs into function parameters - passing by value versus by reference, default arguments, const parameters, and how the choice affects whether your function can change the caller's data.
Frequently Asked Questions
How do you write a function in C++?
Give it a return type, a name, parentheses for parameters, and a body in braces: int add(int a, int b) { return a + b; }. Call it by name with arguments, like add(2, 3). If the function does not return anything, use void as the return type.
What is the difference between a function declaration and a definition in C++?
A declaration (or prototype) tells the compiler a function's name, return type, and parameters, ending in a semicolon: int add(int a, int b);. A definition also provides the body in braces. You can declare a function before main and define it later - the declaration lets you call it before the definition appears.
What happens if a C++ function doesn't return a value?
For a void function, nothing - it simply ends. But for a non-void function, reaching the end without a return is undefined behavior: the caller gets a garbage value and the program may misbehave. Most compilers warn about this; always return a value on every path of a non-void function.