A function is a named, typed block of code: a return type, a name, a parameter list and a body. It must be declared before it is called.
Declaration vs definition
#include <iostream>
int add(int a, int b); // declaration (prototype): signature only
int main() {
std::cout << add(2, 3) << '\n'; // OK: the compiler has seen the declaration
}
int add(int a, int b) { // definition: signature + body
return a + b;
}5| Part | Example | Notes |
|---|---|---|
| Return type | int, void, auto | void = returns nothing; auto = deduced from return (C++14) |
| Name | add | Can be overloaded (same name, different parameters) |
| Parameters | (int a, int b) | Each is a local variable initialised from the argument |
| Trailing return | auto add(int a, int b) -> int | Useful when the type depends on parameters |
| Specifiers | inline, constexpr, static, noexcept, [[nodiscard]] | Change linkage, evaluation or guarantees |
Return values
#include <iostream>
#include <string>
#include <utility>
auto average(double a, double b) { return (a + b) / 2; } // deduced: double
std::pair<int, int> divmod(int a, int b) { return {a / b, a % b}; } // two results
[[nodiscard]] bool save(const std::string& path) { return !path.empty(); }
void greet(const std::string& who) {
if (who.empty()) return; // early return from a void function
std::cout << "Hello, " << who << '\n';
}
int main() {
std::cout << average(3, 4) << '\n';
auto [q, r] = divmod(17, 5);
std::cout << q << ' ' << r << '\n';
greet("Ada");
greet("");
if (!save("out.txt")) std::cout << "failed\n";
}3.5
3 2
Hello, AdaFunction call mechanics
Arguments evaluated
In unspecified order, then copied/bound into the parameters.
Stack frame pushed
Parameters and locals live in the new frame (automatic storage).
Body runs
Until
returnor the closing brace.Frame popped
Locals are destroyed (destructors run, in reverse order). The return value is handed back — often constructed directly in the caller's space (copy elision).
#include <iostream>
int& broken() {
int local = 42;
return local; // warning (error with -Werror): reference to stack memory returned
}
int main() { std::cout << broken() << '\n'; }main and static locals
#include <iostream>
int nextId() {
static int counter = 0; // initialised once, lives for the whole program
return ++counter;
}
int main() {
nextId(); nextId();
std::cout << nextId() << '\n';
}3What is copy elision / RVO?