简体   繁体   中英

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?

How to work around pointer casting... to avoid unaligned memory access?

Use memcpy(&value, data, sizeof value); to transfer the data instead of *((uint32_t *) data) . A good compiler will emit efficient code.

uint8_t data[4] = { 1,2,3,4};
uint32_t value;
memcpy(&value, data, sizeof value);

... or insure the uint8_t value[] is aligned with a union , alignas via *alloc()

union {
  uint8_t data[4];
  uint32_t d32;
} x;
...  
test_func(x.data) {

#include <stdalign.h>
alignas(uint32_t) uint8_t data[4] = { 1,2,3,4};
test_func(data);

uint8_t *data = malloc(sizeof *data * 4);
...
test_func(data);
free(data);

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

You can't (eg 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 eg assert(3) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM