Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Wordsmithing, new NCCE/CS pair

...

Code Block
bgColor#FFcccc
langcpp
// i is modified twice in the same full expression
i = ++i + 1;  

// i is read other than to determine the value to be stored
a[i++] = i;   

Note that not Not all instances of a comma in C++ code denote a usage of the comma operator. For example, the comma between arguments in a function call is not the comma operator.Note that overloaded operators do not affect the defined-ness of expressions Additionally, overloaded operators behave the same as a function call, with the operands to the operator acting as arguments to a function call.

Page properties
hiddentrue

This entire rule will need to be re-evalulated for C++17, because the order of evaluation has been tightened there. For instance, the

...

example of a[i++] = i; will now be well-defined.

See http://en.cppreference.com/w/cpp/language/eval_order, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r3.pdf, and http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0400r0.html.

Noncompliant Code Example

...

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

Noncompliant Code Example

The call to func() in this noncompliant code example has undefined behavior because the argument expressions are unsequenced:

...

Code Block
bgColor#ccccff
langcpp
extern void func(int i, int j);
 
void f(int i) {
  int j = i++;
  func(j, i);
}

Noncompliant Code Example

This noncompliant code example is morally equivalent to the previous noncompliant code example. However, instead of calling a function directly, this code calls an overloaded operator<<(). Overloaded operators are equivalent to a function call and have the same restrictions regarding the sequencing of the function call arguments. Consequently, this noncompliant code example has undefined behavior.

Code Block
bgColor#FFcccc
langcpp
#include <iostream>
 
void f(int i) {
  std::cout << i++ << i << std::endl;
}

Compliant Solution

In this compliant solution, two calls are made to operator<<(), ensuring that the arguments are printed in a well-defined order.

Code Block
bgColor#ccccff
langcpp
#include <iostream>
 
void f(int i) {
  std::cout << i++;
  std::cout << i << std::endl;
}

Noncompliant Code Example

The order of evaluation for function arguments is unspecified. This noncompliant code example exhibits unspecified behavior but not undefined behavior:

...

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.

Compliant Solution

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

...