#define is_aligned(POINTER, BYTE_COUNT)
(((uintptr_t)(const void *)(POINTER)) % (BYTE_COUNT) == 0)
The cast to void *
(or, equivalenty, char *
) is necessary because the standard only guarantees an invertible conversion to uintptr_t
for void *
.
If you want type safety, consider using an inline function:
static inline _Bool is_aligned(const void *restrict pointer, size_t byte_count)
{ return (uintptr_t)pointer % byte_count == 0; }
and hope for compiler optimizations if byte_count
is a compile-time constant.
Why do we need to convert to void *
?
The C language allows different representations for different pointer types, eg you could have a 64-bit void *
type (the whole address space) and a 32-bit foo *
type (a segment).
The conversion foo *
-> void *
might involve an actual computation, eg adding an offset. The standard also leaves it up to the implementation what happens when converting (arbitrary) pointers to integers, but I suspect that it is often implemented as a noop.
For such an implementation, foo *
-> uintptr_t
-> foo *
would work, but foo *
-> uintptr_t
-> void *
and void *
-> uintptr_t
-> foo *
wouldn't. The alignment computation would also not work reliably because you only check alignment relative to the segment offset, which might or might not be what you want.
In conclusion: Always use void *
to get implementation-independant behaviour.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…