We sometimes store pointers to `CRBTree` in `CRBNode*` variables, so we
must make sure CRBTree has matching alignment guarantees. We already
check for that with static-assertions.
This commit aligns CRBTree with CRBNode for 2-byte aligned machines.
While at it, add a short comment explaining what the unions are for.
Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com>
c795b7657f
On m68k, 32bit integer are aligned to only 2 bytes. This breaks
assumptions and a static assertion of c-rbtree.
Explicitly require that the first field is aligned to at least 4 bytes.
This fixes the build and ensures that all valid pointers to a CRBTree have
the lowest two bits unset (so they can be used for storing 2 additional flags).
Use a union instead of aligning __parent_and_flags itself. That is
because alignas() cannot lower the natural alignment, so if we would
want to align __parent_and_flags, we could only do
alignas(sizeof(unsigned long) > 4 ? sizeof(unsigned long) : 4)
That would not be correct if "long" is 8 bytes long but had a natural
alignment of only 4. The union allows us to specify an alignment
of at least 4, but otherwise follow natural alignment.
10d973a9e6
There are some Debian-supported architectures where `max_align_t` is
only aligned to 4-bytes. This is unfortunate and breaks our assumptions.
While glibc-malloc still guarantees 8 / 16 bytes alignment, this is not
necessarily guaranteed by the C standard (and alternative allocators
will deviate (see jemalloc, for instance)).
Fortunately, we only need 2 flags, so a 4-byte alignment is more than
enough.
Reported-by: Thomas Haller
Signed-off-by: David Rheinsberg <david.rheinsberg@gmail.com>
https://github.com/c-util/c-rbtree/pull/4