Reputation: 101
So, in my program, I have a variable
uint32_t buffer[16];
However, there are some times where I need to treat this as
uint8_t char_buffer[64];
The most obvious solution is a union. However, out of intellectual curiosity, is there another way to tell the compiler that I want to treat the array as an array of some arbitrary type? Something along the lines of
((uint8_t *)buffer)[i]
?
Upvotes: 1
Views: 362
Reputation: 46960
The ISO C99 standard says:
When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.
This says that if uint8_t
is typedef unsigned char
(and it must be if uint8_t
exists in your system at all), then your code must work: array reference is equivalent to a dereferenced pointer + int addition.
Note that this works only when casting to char
. Casting the other way or to anything else is only guaranteed to work in the sense that you can eventually cast back, and the final will be equal to the original value. For example, you couldn't cast from an array of 32-bit longs to an array of 16-bit shorts and be sure of anything under the standard, though it's likely to work in practice with most CPU/compiler combinations.
Upvotes: 3
Reputation:
The casting approach is perfect. It will make the compiler treat the array as an array of ints. In your particluar case, use
((uint32_t *)buffer)[index];
As @JerryCoffin points out, however, there's a probem with alignment. If you statically allocate the array statically as a char []
, it won't necessarily be 4-byte aligned (which is needed for integers). If you surely want to avoid this problem, use malloc()
as it guarantees an appropriate alginment.
Upvotes: 4