I think this post is missing that one cannot write a memory allocator that returns objects of different types in conforming/correct C. I.e. you can't write malloc because it violates the type aliasing restrictions.
This can be worked around by putting the allocator in a separate object file (no LTO) or shared library, or by annotating it with compiler attributes that locally switch off aliasing, or by hoping the compiler doesn't exploit the UB inherent in the allocator to your ruin.
Same game in C++ as of the last time I checked, but at least there's placement new and std::launder as workarounds, which strictly speaking need to be used when creating objects with malloc too.
> no actual replacement occurring, rather a simple recasting, since both structs have the same memory footprint
Can't do that either I'm afraid for much the same reason, need to memcpy over the memory and trust the compiler to elide said copy
Interesting. I don't code in C for a living, and I wasn't familiar with strict aliasing -- thanks for sharing your thoughts.
> Can't do that either I'm afraid for much the same reason, need to memcpy over the memory and trust the compiler to elide said copy
Would this apply even to mmap-ed memory? Especially for the bit you're quoting, I guess it can be fixed with a union (or even by using the same struct for both purposes). But since the TAlloc_malloc function returns a pointer to void *, to a location in memory that hasn't been used for any other purposes, perhaps this isn't a violation?
On another note, I was playing around a bit with strict aliasing rules, and oddly enough, the compiler that ships with Monterey (ARM mac) shows no warnings even for code that violates the rules blatantly. Same code threw a warning with GCC (I used an online compiler).
The memory allocator I wrote doesn't throw any warnings using GCC either, but I guess that doesn't mean much.
JonChesterfield|4 years ago
This can be worked around by putting the allocator in a separate object file (no LTO) or shared library, or by annotating it with compiler attributes that locally switch off aliasing, or by hoping the compiler doesn't exploit the UB inherent in the allocator to your ruin.
Same game in C++ as of the last time I checked, but at least there's placement new and std::launder as workarounds, which strictly speaking need to be used when creating objects with malloc too.
> no actual replacement occurring, rather a simple recasting, since both structs have the same memory footprint
Can't do that either I'm afraid for much the same reason, need to memcpy over the memory and trust the compiler to elide said copy
averagedev|4 years ago
> Can't do that either I'm afraid for much the same reason, need to memcpy over the memory and trust the compiler to elide said copy
Would this apply even to mmap-ed memory? Especially for the bit you're quoting, I guess it can be fixed with a union (or even by using the same struct for both purposes). But since the TAlloc_malloc function returns a pointer to void *, to a location in memory that hasn't been used for any other purposes, perhaps this isn't a violation?
On another note, I was playing around a bit with strict aliasing rules, and oddly enough, the compiler that ships with Monterey (ARM mac) shows no warnings even for code that violates the rules blatantly. Same code threw a warning with GCC (I used an online compiler).
The memory allocator I wrote doesn't throw any warnings using GCC either, but I guess that doesn't mean much.
averagedev|4 years ago