How I think about C99 strict aliasing rules

bwidlar | 65 points

It really seems like the compiler writers have gone insane in the last decade or so. Any reasonable person would look at the standard and conclude the intent is to describe what is required to write super-portable programs. Yes, you could have 1s-complement or sign-magnitude integers, so you can't rely on signed overflow for portable code. Yes, you could have separate address spaces for floating point and integers, so you can't rely on cross-type pointer casts or address arithmetic for portable code.

But the compiler writers are using "undefined behavior" as justification to break code on machines that don't have weird address spaces and don't use 1-s complement integers.

So the result... anyone who wants C/C++ to just be a high level assembler is going to need to do all their arithmetic with unsigned and all their pointers as char. Say goodbye to readability or type safety.

xscott | 2 years ago

It's a good point that aliasing issues may show up as different warnings, like maybe-uninitialized in the example. Those warnings are often not obvious at all.

lloda | 2 years ago

Beyond this, one thing I have been putting thoughts into is removing integer promotion and the implicit casts (except for void*) and use explicit static/dynamic casts (not with the horrible c++ syntax). I also thought about static and dynamic consts, but if I understood well, constant folding would be one of the easiest optimizations to do, then that would not be worth it. I still wonder what typedef/typeof/_Generic are doing into C. They may be "cheap" to implement, but could lead to excessive generalizations with a strong smell of Rube Goldberg Machine (happening in the linux kernel).

sylware | 2 years ago

I have always imagine LTO to be such a huge pandora's box regarding this type of issues (e.g. the removal of the impicit memory barrier between function calls) that the fact that it isn't (e.g. many distributions enable lto by default) means that either these problems are way overblown or compilers are still keeping barriers between function calls internally.

AshamedCaptain | 2 years ago

For code that has to do clever things with types, I've now given up on the C type system and just copy bytes through arrays of uint64_t instead. I miss structs but overall the loss is workable. Atomics through the non-standardised intrinsics that work on normal types instead of the _Atomic qualified ones.

JonChesterfield | 2 years ago

This was a good article, and more such articles with examples are needed because understanding how pointer aliasing works can yield significant performance gains, since the compiler can be directed to make optimizations it would otherwise not make.

Annatar | 2 years ago

linux kernel defaults to 'no-strict-aliasing'.

I wonder if this statement is correct: "always do -fno-strict-aliasing by default, only do -fstrict-aliasing where the performance bottleneck is"? It seems like a compromise between safety(less UB) and performance to me.

synergy20 | 2 years ago

Why was the "How" removed from the title? "How I think about C99 strict aliasing rules" is surely much more appropriate?

mort96 | 2 years ago