4 ms·
> Casting about through `void ` and `char * ` is gross, dangerous, and often runs afoul of alignment problems.* This just highlights why strict aliasing rules
by Too 8y ago
> Casting about through `void ` and `char * ` is gross, dangerous, and often runs afoul of alignment problems.*
This just highlights why strict aliasing rules exists. Because the exact same alignment problems is what you get when you type pun. Looking at the raw data as a char* or memcpy'ing it just makes it more visible that what you are doing is wrong.
The only valid reason to do type punning is to serialize data and then deserialize it back to exactly the same type. And since type puning with char* is defined as ok so there is no problem. I am having a really hard time seeing other valid reasons to do type punning and have never ever had to use it myself.
Seriously, why are people upset over strict aliasing? What is the valid use case for type punning that people are missing?
- camgunz 8y agoMostly you run into problems either using the "inheritance" pattern, or with discriminated unions. These are pretty common in C. There really is no alternative to inheritance because if you don't type pun you end up needing to copy a lot (or you can pass around pointers to internal members but it's really easy to lose track of memory that way). And there's also not really an alternative for discriminated unions; the functionality is pretty unique. You can pull the polymorphism out of the type up to the top of your control flow, but that severely degrades your locality. In other words, at some point you have different batches of functions for each "type", but you don't realize that's what they are until you trace the call graph all the way up. Of course, sometimes that's preferable to avoid branching, but at least w/ discriminated unions you get the option.
- Too 8y ago1. Discriminated unions don't have any issues with strict aliasing, you are allowed to read a union member as long as it was the last union member being written to, and the tag-member helps you identify that. 2. If you are trying to retrofit polymorphism in C maybe you are using the wrong tool for the job. 3. If you really want polymorphism you can create baseclass-struct with a void* this pointer and a bunch of function pointers as instance-functions. To "override" the struct you just instantiate it with different function pointers. If you want to inherit an existing struct you add a void* super-member into your this-data and instantiate it explicitly. For any function you don't want to override you use just call the existing function function and pass in you super-data as this. This is also safe as each subclass implementation only casts the void* this into itself which is a known struct of the same type as was last written to. You do have to split the data and keep super-class data in another struct one pointer-hop away but that shouldn't be a big issue.