When I answered this question, I wrote:
First, it is important to note that it is not only the behaviour of the user program that is undefined, it is the behaviour of the compiler that is undefined.
But there was disagreement in a comment, so I want to ask the question here:
If the source code contains Undefined Behaviour, is it only the behaviour of the translated machine code that is undefined, or is the behaviour of the compiler undefined, too?
The standard defines the behaviour of an abstract machine (1.9):
The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. This International Standard places no requirement on the structure of conforming implementations. In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.
Maybe the question is if the compiler is a part of that machine, and if yes, if that part is allowed to behave in an undefined way?
A more practical version of this question would be:
Assume a compiler would crash or not produce any output when it finds UB on all control paths, like in this program:
int main() {
complex_things_without_UB();
int x = 42;
x = x++; //UB here
return x;
}
but otherwise it would always produce correct binaries. Would this still be a standard-compliant compiler?
If a code has undefined behaviour it means that the standards does not know how to handle such thing. Thus it can give any output. I think it doesn't have to do with compiler as it doesn't make sense. It makes sense that it has to be the implementation that works according to standards.
So, if standards don't know how to handle such code, then how can compilers give a defined output?