Search code examples
ccastingundefined-behavior

How to work around pointer casting in C to avoid unaligned memory access?


I recently learned that pointer casting could trigger unaligned memory access, such as in

void test_func(uint8_t *data) {
        /*The rest of the code removed for clarity*/
    uint32_t value = *((uint32_t *) data);
}

But how can I work around it, if I really need to cast pointers? In the example above, what if I have to access data as an uint32_t but still want to avoid unaligned memory access?


Solution

  • How to work around pointer casting in C to avoid unaligned memory access?

    You can't (e.g. on x86-64 unaligned memory access are possible, but slow; it might also be the case on Arduino-s).

    See also _Alignas and _Alignof operators of C11.

    On many implementations, a pointer can be casted back and forth from intptr_t and you could then play bitwise tricks.

    In the example above, what if I have to access data as an uint32_t but still want to avoid unaligned memory access?

    You need to ensure that the caller of test_func is passing a well aligned pointer.

    You could be helped by tools like Frama-C, the Clang static analyzer, or perhaps, at end of spring 2021, Bismon

    You might #include <assert.h> and add, as the first statement of your test_func : assert((intptr_t)data % sizeof(uint32_t) == 0); ; see e.g. assert(3).