SSO-23
SSO-23 copied to clipboard
Alternative solution by using tagged pointer
Because new operator is
required to return a pointer suitably aligned to hold an object of any fundamental alignment.
the pointer to struct long's char
array always have at least 4 low zero bits on a 64-bit OS (3 on a 32-bit OS) and we can take advantage of them to simplify the implementation with the use of tagged pointer
To do that on a big-endian system we just need to move the ptr
field to the last position so that ptr's LSB is also the last byte of the struct in memory
struct long {
size_type size;
size_type capacity;
CharT* ptr;
};
Now the least significant bit of ptr becomes a tag bit
- If it's zero: we're in short mode. The last byte stores
11 - size
or23 - size
just like your solution - If it's one: we're in long mode. Clear the bit and dereference the char array like normal
This is neat.
But it is guaranteed to work only when the buffer is allocated by malloc()
(used by new
operators).
It fails if the field points to static data and, possibly, to stack area.
This is neat. But it is guaranteed to work only when the buffer is allocated by
malloc()
(used bynew
operators). It fails if the field points to static data and, possibly, to stack area.
How can it point to stack area? The buffer is handled internally by the class by calling new
, and just like all other allocations, the caller is required to specify the alignment if required, for example by using std::aligned_alloc
if an alignment value larger than new
is required. No external objects can modify the pointer to point to some other non-aligned userspace area. We can always specify the alignment because it's required for SIMD code
Or do you mean placement new? It's completely irrelevant to this because it affects the allocation of the object, not the buffer that the object points to