|
|
|
|
|
by tsimionescu
677 days ago
|
|
The original code is not invalid, even by the standard. It's not even undefined behavior. It is perfectly well defined as equivalent to `return true` according to the standard, or it can be implemented in the more straightforward way (add one to a, compare the result with a, return the result of the comparison). Both are perfectly valid compilations of this code according to the standard. Both allow inlining the function as well. Note that also `return 1 < 0` is also perfectly valid code. The problem related to UB appears if the function is inlined in a situation where a is INT_MAX. That causes the whole branch of code to be UB, and the compiler is allowed to compile the whole context with the assumption that this didn't happen. For example, the following function can well be compiled to print "not zero": int foo(int x) {
if (x == 0) {
return stupid(INT_MAX);
} else {
printf("not zero");
return -1;
}
}
foo(0); //prints "not zero"
This is a valid compilation, because stupid(INT_MAX) would be UB, so it can't happen in a valid program. The only way for the program to be valid is for x to never be 0, so the `if` is superfluous and `foo` can be compiled to only have the code where UB can't happen.Eidt: Now, neither clang nor gcc seem to do this optimization. But if we replace stupid(INT_MAX) with a "worse" kind of UB, say `*(int*)NULL = 1`, then they do indeed compile the function to simply call printf [0]. [0] https://godbolt.org/z/McWddjevc |
|
Functions have parameters. In the case of the previous function, it is not defined if its parameter is INT_MAX, but is defined for all other values of int.
Having functions that are only valid on a subset of the domain defined by the types of their parameters is a commonplace thing, even outside of C.
Yes, a compiler can deduce that a particular code path can be completely elided because the resulting behaviour wasn't defined. There is nothing surprising about this.