How to determine if memory is aligned?
EDIT: casting to long
is a cheap way to protect oneself against the most likely possibility of int and pointers being different sizes nowadays.
As pointed out in the comments below, there are better solutions if you are willing to include a header...
A pointer p
is aligned on a 16-byte boundary iff ((unsigned long)p & 15) == 0
.
Other answers suggest an AND operation with low bits set, and comparing to zero.
But a more straight-forward test would be to do a MOD with the desired alignment value, and compare to zero.
#define ALIGNMENT_VALUE 16u
if (((uintptr_t)ptr % ALIGNMENT_VALUE) == 0)
{
// ptr is aligned
}
#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.