Indeterminately sequenced evaluations complete one after the other, but the language does not specify which evaluation comes first. The behavior remains defined, although the result can vary between executions or compilers. section 19.2
unsigned add(unsigned* x, unsigned const* y) [[unsequenced]] {
return *x += *y;
}
int main(void) {
unsigned a = 3;
unsigned b = 5;
printf("a = %u, b = %u\n", add(&a, &b), add(&b, &a));
}
Two function calls update shared objects through pointer arguments. One call completes before the other, but either call may run first. section 19.2
Two valid outcomes
If add(&a, &b) runs first, the values become a = 8 and b = 13. If add(&b, &a) runs first, they become a = 11 and b = 8. Both outcomes are valid, and gcc and clang may choose differently without warning. section 19.2
TAKEAWAY
- Side effects inside function calls can produce indeterminate results without producing undefined behavior. section 19.2
