Search code examples
cundefined-behaviormemory-alignmentc11pointer-arithmetic

Is pointer arithmetic still well defined after casting with alignment violation?


I know that the result of pointer casting with alignment violation invokes undefined behaviour once dereferenced.

But what about pointer casting for address calculation only (without dereferencing)?

void *addr_calc(single_byte_aligned_struct_t *ptr, uint32_t dword_offset)
{
    uint32_t *dw_ptr = (uint32_t *)ptr;

    return dw_ptr + dword_offset;
}

Let's assume the value of ptr is X. Is it guaranteed that that addr_calc() will return X + sizeof(uint32_t) * dword_offset?

My assumption was that it is but recently I saw the following in the C11 standard, section J.2 Undefined behaviour

— Conversion between two pointer types produces a result that is incorrectly aligned (6.3.2.3).

If I understood it correctly, the casting itself invokes undefined behaviour, not only dereferencing, which means that even the pointer arithmetic may behave unpredictably in such case. Am I right?


Solution

  • This can in fact result in undefined behavior if ptr is not properly aligned for uint32_t. Some systems might allow it but others could trigger a fault.

    A safe conversion would be to char *, then doing the pointer arithmetic on that.

    return (char *)ptr + dword_offset * sizeof(uint32_t);