7 ms·
Why type-punning breaks strict-aliasing
- prodigal_erik 15y agoEvery good programmer needs to understand pointers and aliasing at this level. And maybe it would convince some of them what a tremendous waste of time it is to try doing reliable and productive work using raw pointers.
- shadowfox 15y agoWhat are you trying to imply here?
- prodigal_erik 15y agoIf more people were aware of how many obscure and subtle ways C code can be seriously wrong but look fine, we wouldn't have so many apps with security flaws that blow up randomly, because people wouldn't be choosing C so often. This is a very well-written example of the kind of pitfalls that ought to be driving people to saner runtimes, which I wish someone had convinced me of before I wasted years trying to do reliable work in C and then C++.
- sqrt17 15y agoThere are really two valid uses for aliasing/type-punning: one is bit twiddling (e.g. you have a data structure where you want to access specific bits or bytes, e.g. the exponent of floats, or having a mixed stream of floats/characters/shorts), and the other one is type-punning as poor man's polymorphy, as in different sockaddr structures in the C library or the representation of event types in Xlib. It's easy to claim that these uses don't exist, but they do occur in every larger piece of C software (especially when that large piece of software has performance-critical parts, which is increasingly the main use of C). And in both cases, the compiler breaks cases where the aliasing is introduced in the current function, and also exploited there; this should be reasonably easy to detect (compared to the general aliasing problem, which is unsolvable).
- premchai21 15y agoIt seems to me that it should be possible to use memcpy between multiple C variables to avoid straight type-punning, and then have the compiler reöptimize it into aliased memory or registers (assuming the source isn't volatile memory or something like that, in which case things get trickier anyway). This is roughly what I do in my C programs these days. In some cases, declaring alignment may be hard to do portably; it's probably possible to use union tricks to force there to exist a dummy statement that implies certain alignment without breaking the aliasing rules, but I don't know for sure since I haven't run into such cases in practice yet. As a nonrepresentative example, the simple function: uint64_t foo(char x[8]) { uint64_t y; memcpy(&y, &x[0], 8); return y; } gets compiled into a single « movq (%rdi), %rax » by gcc -S -O2 on my AMD64 machine with GCC 4.6.1.
- mansr 15y agoPolymorphism as with sockaddr and XEvent types is safe. The values are always (in a correct program) read as the same type they were written so there is no type punning.