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]>
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.
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.
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.
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.
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.
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