C++ Logo


Advanced search

(wrong string) ödinger's UB

From: (wrong string) énárd Szolnoki <cpp_at_[hidden]>
Date: Sat, 3 Dec 2022 15:19:56 +0000
On Sat, 3 Dec 2022 09:32:05 -0500
Jason McKesson via Std-Discussion <std-discussion_at_[hidden]>

> [intro.abstract]3 says "executing that program with that input". That
> is, if you have conditional UB, and never get any "input" that would
> trigger the conditional UB, then you have well-defined behavior.

In my example the input would trigger conditional UB in one of the
possible executions.

Breaking down my analysis:

The program:

#include <iostream>

void foo(int, int) {}

int main() {
  int i;
  foo(i=0, i=1); // Unspecified whether i is 0 or 1 after this line
  int j;
  std::cout << "% Type " << i << " to not invoke UB" << std::endl;
  std::cin >> j;
  if (i != j) {
    *(int*)nullptr = 42;

The execution:

$ ./a.out
% Type 0 to not invoke UB

https://timsong-cpp.github.io/cppwp/n4868/intro.abstract#3 applies for
the line marked with the comment, for the unspecified evaluation order
of the function arguments. Emphasis on the following sentence:

"An instance of the abstract machine can thus have more than one
possible execution for a given program and a given input."

Therefore the program with the input "0" has two possible executions,
 where `i` ends up being 0 or 1 after the call to `foo`.

One of these executions evaluate the condition `i != j` as true and
invoke an undefined operations. Therefore

There is no consideration that other execution would have printed "Type
1 to not invoke UB", and a user might have chosen a different input.

Received on 2022-12-03 15:20:03