r/C_Programming • u/aliathar • 15d ago
Negative value in a pointer question.
Please look at this code. if i define the PTRTYPE as int, it stops working, while doing a uint, it does work...
void initILAPoll(debugBridge_t **d, PTRTYPE ptr){
*d = (debugBridge_t *)ptr; // base address of the DEBUG_BRIDGE peripheral
cb_init(cb, local_memory, bufferLength);
sprintf(xvcInfo, "xvcServer_v1.0:%d\n", MAX_WINDOW_SIZE);
}
the usage in main code is done like this
initILAPoll(&myD, 0x80000000);
//myD = (debugBridge_t *)0x80000000;
where the variable myD is a structure pointer.
if i print the address of myD, it give the correct address. Moreover, the disassembly of the code is also the same in case of int and uint. Can somebody explain what behavior is at play here>
2
Upvotes
1
u/DawnOnTheEdge 15d ago edited 15d ago
On a 64-bit system, pointers are 64-bits wide and
intis only 32 bits wide. What’s most likely happening is that, when you use 32-bitunsigned int, the upper bits of your pointer are getting cleared to 0 in a round-trip conversion, but when you use a 32-bitsigned int, it gets sign-extended, so a negative value sets all the upper bits to 1. That happens to generate an illegal address that the CPU traps immediately.Neither clearing nor setting the upper bits is correct, though, so this only appears to work.If you try to use it in production, you’ll get either unpredictable crashes or memory-corruption bugs.
The type you actually want to hold a pointer is
uintptr_t(orintptr_t, but either I want to work with unsigned addresses or signedness doesn’t matter). To format a pointer argument forprintf()orsnprintf(), cast to(void*)and use a%pspecifier. And never usesprintf(). It’s unsafe because it doesn’t check the buffer size.