2 ms·
I've been putting off replying until at a desk but that's not worked out. What used to be struct { atomic_uint64_t count; uint32_t X; uint32_t Y; void
by JonChesterfield 4y ago
I've been putting off replying until at a desk but that's not worked out.
What used to be
struct {
atomic_uint64_t count;
uint32_t X;
uint32_t Y;
void * Z;
};
is now a uint64_t[4] with bytewise copies to get the void* back and intrinsics for the atomic operations.
Functions all take a uint64_t* so the array length is discarded. Means some functions can take a pointer to the refcount field and others to the first data field for when there is no refcount involved.
uint64_t has no magic aliasing properties, but pointers and doubles can be memcpy'd into it, and things like uint64_t data[2048] in .rodata can have whatever set of objects one likes embedded in it. Slightly sketchy is casting addresses directly to uint64_t instead of memcpy but clang does not yet mangle code doing that. Will change static data to asm when it does.
This makes writing correct C moderately harder but has the redeeming feature that type based alias analysis is no longer a hazard.