2 ms·
The first example is wrong. "The optimizer is not allowed to change the program semantics" - of course it can, especially in multi threaded environment. You cou
by Sankozi 3y ago
The first example is wrong. "The optimizer is not allowed to change the program semantics" - of course it can, especially in multi threaded environment. You could add global variable and replace undefined behavior with global variable assignment and the program would still work differently depending on optimization levels.
- kevincox 3y agoI think while you are technically correct it isn't really meaningful. The optimizer isn't allow to change the guaranteed semantics of the program. The rule isn't that there is no observable difference between unoptimized and optimized because what would that even mean? What is the baseline? You could just as easily say that the optimized version is correct and the optimized one is "wrong"? As long as both versions don't break the semantics of the language there is nothing that would make the optimized version "more correct" than the other one. If my compiler puts a thousand nop instructions between every line of code that would also "change program semantics" according to your strict definition, but no one would ague that it is an invalid compiler.
- Sankozi 3y agoThe thing is the guaranteed semantics are something totally different than what you usually expect when looking at the code. That is why the term "observable" is often introduced when explaining how optimizer works (or can work). The example is wrong because compiler is allowed to do optimization in such context not due to the undefined behavior. The "within-thread as-if-serial" guarantees are still preserved and optimization still can be done even if undefined behavior is removed from the example.