In practice, there is no such thing as "no optimization" in C.
If you map every variable read to a memory read and every variable written to a memory store, your code will run incredibly slow. At the least, you will want to do register allocation and constant folding.
That's not so bad w.r.t. undefined behavior, but you also will want to do dead code elimination. If you don't, program size will blow up (think of macro definitions for DEBUG) That dead code elimination is what causes many of those portability issues.
In C, undefined behaviour is the price we pay for small code size and fast execution.
Also, are you sure C# doesn't optimize code marked DontOptimize? I'm asking because the documentation at http://msdn.microsoft.com/en-us/library/system.runtime.compi... says "The method is not optimized by the just-in-time (JIT) compiler or by native code generation (see Ngen.exe) when debugging possible code generation problems.", but doesn't tell what that last phrase means.
But the whole "this code might be removed during optimization" isn't exactly true. The compiler has to keep the meaning of your code the same. But once you introduce undefined behavior into the code, everything is meaningless from then on and gcc can do tons of wacky stuff.
>Why has nobody pushed for marking key sections of code with "don't optimise away" flags?
The issue isn't that certain code is optimized away. That's just a symptom of the fact that it's incorrect C code relying on the way a specific system treats undefined behavior. Checking for overflow can be done with correct C code that doesn't rely on undefined behavior, so putting in a hack that lets incorrect C work in some situations does not seem like the right answer.
(Most) things that are undefined behavior are so for a reason.
In this case - you don't know if the system you're on even stores numbers as twos complement. And if it doesn't, it may not have the same behavior. So even the unoptimized version may fail.
I think in most cases, people writing code to check for overflow do know whether the system they're on stores integers as twos complement, and they'll have a pretty good idea what will happen when overflow occurs. A portable approach for this sort of thing would be very useful, but in the mean time, perhaps we could settle for compilers that don't strip out reasonable code?
Why has nobody pushed for marking key sections of code with "don't optimise away" flags?
In C# you have this: