Assume we have a Container
maintaining a set of int
values, plus a flag for each value indicating whether the value is valid. Invalid values are considered to be INT_MAX
. Initially, all values are invalid. When a value is accessed for the first time, it is set to INT_MAX
and its flag is set to valid.
struct Container {
int& operator[](int i) {
if (!isValid[i]) {
values[i] = INT_MAX; // (*)
isValid[i] = true; // (**)
}
return values[i];
}
std::vector<int> values;
std::vector<bool> isValid;
};
Now, another thread reads container values concurrently:
// This member is allowed to overestimate value i, but it must not underestimate it.
int Container::get(int i) {
return isValid[i] ? values[i] : INT_MAX;
}
This is perfectly valid code, but it is crucial that lines (*)
and (**)
are executed in the given order.
- Does the standard guarantee in this case that the lines are executed in the given order? At least from a single-threaded perspective, the lines could be interchanged, couldn't they?
- If not, what is the most efficient way to ensure their order? This is high-performance code, so I cannot go without
-O3
and do not want to usevolatile
.