Finalize Before Return: Avoid Partial Updates
Finalize Before Return: Avoid Partial Updates
Finalize Before Return: Avoid Partial Updates in C++
Prerequisites
1. Why This Matters
1
- Atomic Update Concept
Always build the result completely, then update it once at the end.
When constructing or updating a result object:
- Partial updates can lead to inconsistent states
- Intermediate writes may cause confusion or bugs
- Repeated updates may introduce unnecessary overhead
Do NOT update the output object step-by-step.
Build everything internally, and commit once at the end.
2. What the problem: Partial Updates
2-1. Example
❌ Bad Pattern
1
2
3
4
5
6
7
8
9
10
void process(Result& out)
{
out.value = computeA();
out.flag = checkSomething();
if (!out.flag)
return;
out.extra = computeB(); // partial update
}
outis left in a partially updated state- Hard to reason about correctness
- Risk of inconsistent data
Solution: Build Then Commit
✔ Good Pattern
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void process(Result& out)
{
Result temp;
temp.value = computeA();
temp.flag = checkSomething();
if (!temp.flag)
return;
temp.extra = computeB();
out = std::move(temp); // commit once
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Result process()
{
Result res;
res.value = computeA();
res.flag = checkSomething();
if (!res.flag)
return {};
res.extra = computeB();
return res; // copy elision (C++17)
}
2-2. Benefits
- Output is always valid or unchanged
- Clear logic
- No partial state exposure
- Avoids multiple writes to output object
- Enables copy elision / move optimization
- Better cache locality (build locally, then commit)
✔ DO
- Use local temporary object
- Validate before committing
- Return by value when possible
- Use
std::moveor rely on copy elision
❌ DON’T
- Modify output object incrementally
- Leave partially valid state
- Mix computation and external state update
This post is licensed under CC BY 4.0 by the author.