This is true and when your compiler actually abides by these values it is shocking how many issues just go away. The problem is that gcc and clang are nowhere near a simple implementation, asking the question of how exactly gcc or clang arrived at some given assembly for some given input is a really complicated answer. So much so that it makes me say that the relationship between the programmer and the compiler becomes adversarial. It would be one thing to just have very complicated optimizations but the whole "undefined behavior lets us to anything" approach is what makes it unbearable.
People can (and do) point at the C spec for fault of this and it is true that if the C spec was more strict then these compilers would not have the free pass to do these crazy miscompilations. However there is nothing stopping these compilers from just not doing that, there is nothing stopping them from just defining their own sane behavior for what the C spec defines as undefined behavior. It is no longer the case where we have a dozen or so C compilers that people need to target with their programs, the spec is not the bottom line anymore.
The Plan 9 compilers are the perfect example of getting this right. They define sane behavior that a reasonable programmer would expect for what the C spec calls undefined behavior. They are not gargantuan, their optimizations are not crazy. It is generally easy to understand how the compiler ended up with the assembly you see in the binary. Yet they are competent enough to selfhost an entire OS. The insane complexity of these other C compilers is simply not mandatory. They are not perfect of course it is still possible to write bad code but the result is no longer pathological, which is a giant help when you're actually trying to figure out what is going wrong.