liveBook · Manning

Indeterminately sequenced evaluation

As explained in Modern C, Third Edition

Indeterminately sequenced evaluation is an evaluation relationship in which one evaluation completes before the other, but the language does not specify which occurs first.

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

How Modern C, Third Edition covers it

How deep it goes
Works through two call orders and identifies sequence points, but does not develop the complete sequencing model.
Examples
Uses add(&a, &b) and add(&b, &a), with outputs a = 8, b = 13 or a = 11, b = 8.
What it assumes
Assumes familiarity with C function calls, pointer arguments, object updates, and side effects.
What you can do after
Evaluate defined C code whose side-effect order is unspecified and anticipate differing compiler results.
How it connects
Connects function calls with side effects, sequence points, and operand evaluation.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.