Your article contains the perfect example:
> UB on integer overflow is a compiler-only concept
> every target supported by the compiler will do the obvious thing and just produce an overflowing result
Pretty much every computer that matters works the way you expect it to: the value will overflow, some flag will be set, etc. The compiler couldn't care less though. The compiler decrees that it shall be undefined. You know it works but it doesn't because the compiler refuses to do what you expect it to do because it's "undefined".
Well then just define it for god's sake. I'm so tired of the uncertainty. Tired of playing these games with the compiler. Undefined? I don't even want to read that word ever again.
Let's define this right now.
-fwrapv
There. It is now defined to be what everyone expects and wants. Now the optimizer won't be getting "clever" with this and generating complete garbage code as result. The compiler's optimizer is no longer your enemy in this case. It won't be erroneously optimizing entire loops to some random constant anymore. One would think they'd emit a warning instead in these cases but no.Strict aliasing is yet another massive pain that you need to deal with because of compilers and their "optimizations". People have actually told me to "launder" pointers through asm statements so the compiler can't make nonsense assumptions about that stuff.
This is C. We do things like write memory allocators. Of course we're going to alias stuff. I have a structure type, I have a byte buffer with the data, of course I want to overlay the type on the byte buffer and just access it directly. Why is it that the compiler just doesn't let me reinterpret memory however I want? Compiler has no business making my life hell because of this.
Turns out the C standard prescribes some "strict aliasing" nonsense because Fortran has it or some other reason nobody really cares about. If you're doing anything at all in C you're probably violating this.
-fno-strict-aliasing
There. You can now do what you want to do without the compiler getting all clever about it and ruining your day with nonsense code generation. Now it won't be reordering your code into nonsense just because it can "prove" that two pointers can't be equal even though you literally assigned one pointer to the other.Over time I've built up this little collection of C compiler flags and they've become unconditional overrides in all my makefiles. No matter what users pass in via CFLAGS or whatever, these little things still get disabled. I have no idea what the performance impact is and honestly I don't care.
There's quite a lot of documented compiler flags, I couldn't evaulate every single one of them. If anyone here knows of any other useful flags that define the undefined, please reply to this comment. I'll add them to my makefiles without thinking twice.