Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

These examples are independent of the order of evaluation of the operands and can be interpreted in only one way.:

Code Block
bgColor#ccccff
langcpp
void f(int i, const int *b) {
  ++i;
  int a = i + b[i];
  // ...
}

...

The first (left) argument expression reads the value of i (to determine the value to be stored) and then modifies i. The second (right) argument expression reads the value of i, but not to determine the value to be stored in i. This additional attempt to read the value of i has undefined  has undefined behavior.

Compliant Solution

This compliant solution is appropriate when the programmer intends for both arguments to func() to be equivalent:

...

Code Block
bgColor#FFcccc
langccpp
extern void c(int i, int j);
int glob;
  
int a() {
  return glob + 10;
}

int b() {
  glob = 42;
  return glob;
}
  
void f() {
  c(a(), b());
}

The order in which a() and b() are called is unspecified; the only guarantee is that both a() and b() will be called before c() is called. If a() or b() rely on shared state when calculating their return value, as they do in this example, the resulting arguments passed to c() may differ between compilers or architectures.

...

In this compliant solution, the order of evaluation for a() and b() is fixed, and so no no unspecified behavior occurs:

Code Block
bgColor#ccccff
langccpp
extern void c(int i, int j);
int glob;
 
int a() {
  return glob + 10;
}
  
int b() {
  glob = 42;
  return glob;
}
 
void f() {
  int a_val, b_val;
  
  a_val = a();
  b_val = b();

  c(a_val, b_val);
}

Risk Assessment

Attempting to modify an object in an unsequenced or indeterminately sequenced evaluation may cause that object to take on an unexpected value, which can lead to unexpected program behavior.

...