📦 개념 요약
| 용어 | 의미 |
| RVO (Return Value Optimization) | 임시 객체를 직접 호출자 영역에 생성하여 복사/이동 생략 |
| NRVO (Named Return Value Optimization) | 이름 있는 지역 변수를 반환할 때도 복사/이동 없이 직접 생성 |
✅ RVO (Return Value Optimization)
예제:
Test createTest() {
return Test(); // 임시 객체 반환
}
- Test() 생성 시, 컴파일러가 호출자 스택에 직접 객체 생성
- 그래서 생성자 1번만 호출, 복사/이동 생략됨
➡️ 객체를 “리턴용 임시 공간”에 직접 생성하는 방식
✅ NRVO (Named Return Value Optimization)
예제:
Test createTest() {
Test t;
return t; // 이름 있는 변수 반환
}
- t는 함수 내부 지역 변수지만
- 컴파일러가 t를 호출자 스택에 직접 생성해서 복사/이동 생략 가능
➡️ 단, 조건문 등 분기가 있으면 NRVO가 적용되지 않을 수 있음
🔥 실제 실행 순서 비교
struct Test {
Test() { std::cout << "Constructor\n"; }
Test(const Test&) { std::cout << "Copy\n"; }
Test(Test&&) { std::cout << "Move\n"; }
};
Test make() {
return Test(); // RVO
}
int main() {
Test t = make(); // 생성자만 출력될 수도 있음 (RVO)
}
- 출력 결과:
- C++17 이전: Move or Copy
- C++17 이후: Constructor만 (복사/이동 생략됨 — RVO guaranteed)
🚀 C++17 이후 변경점
✅ C++17부터 RVO는 강제됨 (mandatory copy elision)
Test f() {
return Test(); // RVO 반드시 적용됨
}
- 복사 생성자/이동 생성자가 삭제되어 있어도 컴파일됨 → 객체는 복사 없이 생성됨
⚠️ 주의할 점
| 상황 | RVO/NRVO 적용 여부 |
| return Test(); | ✅ RVO |
| Test t; return t; | ✅ NRVO (C++17 이전에는 optional) |
| if (...) return t1; else return t2; | ❌ NRVO 불가 |
| return std::move(t); | ❌ NRVO 못 함 → 강제로 이동 발생 |
❌ 예시 (NRVO 안 됨):
Test create() {
Test t;
return std::move(t); // 이동 발생 → NRVO 적용 안 됨!
}
📌 정리
| 구분 | 설명 |
| RVO | 임시 객체 직접 리턴 시, 복사/이동 없이 생성됨 |
| NRVO | 이름 있는 객체도 복사 없이 리턴 가능 (조건 있음) |
| C++17 | RVO는 강제 적용, NRVO는 여전히 optional |
| std::move() 사용 | NRVO 못 하게 방해함 (주의!) |
✨ 실전 팁
- 값을 리턴할 때 std::move() 쓰지 마라!
- return std::move(obj); // ❌ NRVO 방해함 return obj; // ✅ NRVO 가능
- 생성자/복사/이동자 로그 찍어서 최적화 확인 가능
- 구조체 반환 비용 때문에 복사비용 걱정하지 않아도 되는 시대임 (C++17+)
반응형
'프로그래밍 > C,C++' 카테고리의 다른 글
| [Modern C++] std::call_once (1) | 2025.08.05 |
|---|---|
| [Modern C++20] 🚀주요 특징 & 설명 (0) | 2025.04.16 |
| [Modern C++20] coroutine (0) | 2025.04.11 |
| [Modern C++20] concept (0) | 2025.04.08 |
| [Modern C++] string_view (0) | 2025.04.02 |