I have this piece of C code (For MSP430 platforms, cl430
compiler):
void function(uint8_t * x){
// This variable is defined in the linker file as "X_ADDR = 0xE000;"
extern uint32_t X_ADDR;
uint16_t i = 0;
uint16_t size = 10;
uint32_t dst_addr = (uint32_t) &X_ADDR;
for (i=0; i < size; i++){
*((uint8_t *) (dst_addr+i)) = *(x+i); // <-- This line shows the warning
}
What I understand is this, but here is where I guess I am wrong:
*((uint8_t *) (dst_addr+i)) = *(x + i);
| | | |
V V V V
*((uint8_t *) (u32 + u16)) = *(u8*+u16);
*((uint8_t *) (u32)) = *(u8*);
*(u8*) = u8;
u8 = u8;
This platform is 16-bits but it supports an extended addressing mode of 20-bits.
Any hint on this? and how should it be done instead? Thanks in advance
You seem to get this on 64 bit compilers that use 64 bit pointers. Converting a 32 bit integer to a 64 bit pointer is questionable and non-portable.
Correct this by using the portable integer type meant to be used for this very purpose:
uintptr_t dst_addr = 0x00FFABCD;
Now it will compile cleanly on all mainstream 64 bit compilers. Tried on gcc, clang icc with -std=c11 -Wextra -Wall -pedantic-errors
, no problems.
In addition, when accessing an absolute address, you will almost certainly need to volatile
qualify the pointer.