C++ Logo

std-discussion

Advanced search

Re: Schrödinger's UB

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Sat, 3 Dec 2022 11:36:49 -0500
On Sat, Dec 3, 2022 at 10:20 AM Lénárd Szolnoki via Std-Discussion
<std-discussion_at_[hidden]> wrote:
>
> On Sat, 3 Dec 2022 09:32:05 -0500
> Jason McKesson via Std-Discussion <std-discussion_at_[hidden]>
> wrote:
>
> > [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.

... and? I don't see the problem here (or rather, I don't see how this
is a distinct problem). If the program gets an input that *cannot*
trigger UB (like, say, 2), then the program has well-defined behavior.



> 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
> 0
> ```
>
> 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
> https://timsong-cpp.github.io/cppwp/n4868/intro.abstract#5.sentence-2
> applies.

It only applies if that actually happens, if it gets an input where it
is possible for the condition to be valid.

In terms of UB, there is no difference between your example and this:

```
#include <iostream>

int main() {
  int j;
  std::cin >> j;
  if (j == 0 || j == 1) {
    *(int*)nullptr = 42;
  }
}
```

This program has UB if the user enters 0 or 1, and the program does
not have UB if the user enters something else.

Received on 2022-12-03 16:38:47