Reputation: 1228
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
Upvotes: 1
Views: 8961
Reputation: 180161
You are converting a 32-bit integer into a 16-bit pointer.
To ensure that your integer type has the same size as a pointer, use uintptr_t
from <stdint.h>
.
And when you treating X_ADDR
as a byte array, it would be a better idea to declare it as such:
extern uint8_t X_ADDR[];
X_ADDR[i] = ...;
Upvotes: 0
Reputation: 214187
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.
Upvotes: 4
Reputation: 4247
It's objecting to the conversion of the integer dst_addr
to a pointer, not the assignment of the uint8_t
$ gcc -c -Wall -W type.c
type.c: In function 'function':
type.c:11:12: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
*((uint8_t *) (dst_addr+i)) = *(x+i); // <-- This line shows the warning
^
and clang offers similar:
$ clang -c type.c -W -Wall
type.c:11:12: warning: cast to 'uint8_t *' (aka 'unsigned char *') from smaller integer type 'unsigned int'
[-Wint-to-pointer-cast]
*((uint8_t *) (dst_addr+i)) = *(x+i); // <-- This line shows the warning
^
(clang 3.4.2; gcc 4.8.5)
Converting from an int to a pointer is always suspect, and I'm not sure there's a way to tell the compiler that you really meant it, at least if you turn on all the warnings (which is a good practice).
Upvotes: 0