For illustrative purposes, I have been trying to find an example, by using gcc, where the output of a program is different with and without optimization enabled (with and without -O3). The purpose of finding such example is to show how optimizations could make an apparently correct program behave different after optimizations have been active if the code contains undefined behaviour.
I have been trying different "combos" of the following program:
// I have tried defining blind in this and in a separate module. The result is the same.
void blind(int const* p) { ++*const_cast<int*>(p); }
#include <iostream>
int constant() { return 0; }
int main()
{
int const p = constant();
blind(&p);
std::cout << p << std::endl;
return 0;
}
I was expecting that, without optimizations enabled, this program will show 1, but with optimizations enabled (-O3) it will show 0 (by replacing std::cout << p by std::cout << 0 directly), but that's not the case. If I replace the initialization by int const p = 0, it will print 0 with and without optimizations enabled, and so the behaviour is again the same.
I have tried different alternatives like doing arithmetic operations (expecting the compiler to prefer to "pre-compute" the value or something), calling blind several times, etc. But nothing works.
NOTE: Preferably, one example where the program won't probably crash in the optimized version.
Now may be my time to shine. I asked this question a while ago and it seems to perfectly demonstrate an example of what you are looking for in a very short/simple program, which I will include below for completeness:
#include <iostream>
int broken_for_loop(){
for (int i = 0; i < 10000; i+= 1000){
std::cout << i << std::endl;
}
}
int main(int argc, char const *argv[]){
broken_for_loop();
}
You can see the discussion/explanation there (long story short, I don't return from a function that should return an int), but I think it does a good job of demonstrating how some UB can be pretty sneaky in presenting itself only in optimized binaries if you're not thinking about it/paying attention to compiler warnings.
Adding in case it wasnt clear:
When compiled without optimization, the program prints 0...9000 and then exits properly. When compiled with -O3 the loop runs forever.
Compiled with: g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With