C++ return Statement: Values, References, RVO, and optional
이 글의 핵심
The return statement finishes execution and passes values back. Learn void returns, reference/pointer pitfalls, RVO, and structured bindings with pair/tuple/optional.
Introduction
The return statement ends a function and passes a value to the caller. In C++, RVO and move semantics often make returning large objects by value efficient—avoid pessimizing with unnecessary std::move on returned locals.
1. return basics
Returning values
#include <iostream>
int add(int a, int b) {
return a + b;
}
double divide(int a, int b) {
return static_cast<double>(a) / b;
}
int main() {
int sum = add(10, 20);
double result = divide(10, 3);
std::cout << "sum: " << sum << std::endl;
std::cout << "divide: " << result << std::endl;
return 0;
}
void functions
#include <iostream>
void printMessage(const std::string& msg) {
std::cout << msg << std::endl;
return; // optional at end
}
void processData(int value) {
if (value < 0) {
std::cout << "cannot process negative\n";
return; // early exit
}
std::cout << "processing: " << value << std::endl;
}
2. Return kinds
By value
Returning std::string, std::vector, etc. by value is idiomatic; rely on RVO/move.
Reference returns
Safe patterns: references to members, to static storage, or to parameters passed in—not to locals.
Pointer returns
If you return new, document who deletes. Never return the address of a local automatic variable.
3. RVO / NRVO
Returning a local by name (return s;) enables NRVO in many compilers. Do not write return std::move(s); for a local named return if it blocks elision.
4. Multiple return values
Use std::pair, std::tuple, structs, or C++17 structured bindings. Use std::optional for “maybe a value.”
5. Common problems
Local reference return
const std::string& bad() {
std::string s = "Hello";
return s; // dangling
}
std::string good() {
std::string s = "Hello";
return s; // OK
}
Missing return on some paths
Non-void functions must return on all paths—enable warnings (-Wreturn-type).
Unnecessary std::move on return
Usually harmful for named locals—prefer return local;.
6. Practical file reader example
The Korean article’s FileReader with optional<string> vs throwing readFileOrThrow is a solid pattern for APIs.
Summary
- return ends the function and optionally yields a value.
- Prefer by value for locals; rely on RVO/move.
- References must refer to valid storage.
- Pointers imply ownership/lifetime rules—document them.
- RVO — avoid
std::moveon returned named locals unless you know you need it. - optional / tuple / pair for multiple or fallible results.
Next: RVO/NRVO, Copy elision, Move semantics.
Related posts
- std::function vs function pointer
- Default arguments
- RVO/NRVO errors
- C++ functions
- Function overloading