How ptr arithmitic works??? It doesn't make any sense....
rempas
rempas at tutanota.com
Sun Dec 4 16:33:35 UTC 2022
First a little bit of theory. A pointer just points to a memory
address which is a number. So when I add "10" to this pointer, it
will point ten bytes after the place it was pointing to, right?
Another thing with pointers is that it doesn't have "types". A
pointer always just points to a location so types are created for
the compiler so we can catch bugs when pointing to places and
trying to manipulate the bytes to a size we probably wouldn't
want to. For example: if you have allocated 4 bytes and then you
try to point to it with a type of "short" for example, then you
could only manipulate 2 of these 4 bytes but you probably
wouldn't and you did something wrong so we do have types and the
compiler requires explicit pointer type casting (in contrast to
C) so it can protect you from these bugs.
This type-casting brings some problem however. So, I played
around it and I figured it out than to get the right location you
expect when returning from a function, you need to do the math
and then cast the whole expression (so the result) and return
that. If you only cast the first value (that is of the different
type) an then do that addition (or whatever expression you want),
it will return a wrong address. But WAIT!!! This doesn't work in
a different example. And I'm braking my head to understand why
and I thought about asking if anyone can help and explain to me
why. Btw, all the testing was made with `ldc` in the `BetterC`
"mode". Code:
```d
import core.stdc.stdio;
import core.stdc.stdlib;
struct MemoryBlock {
char* ptr;
ulong length;
}
void* ptr = cast(void*)0x7a7;
void* right() {
return cast(MemoryBlock*)(ptr + MemoryBlock.sizeof); // Cast
the whole expression between paranthesis. Got the right value!
}
void* wrong() {
return cast(MemoryBlock*)ptr + MemoryBlock.sizeof; // First
cast the `ptr` variable and then add the number. Got a wronge
value...
}
char* return_address_wrong() {
MemoryBlock* local_ptr = cast(MemoryBlock*)ptr;
return cast(char*)(local_ptr + MemoryBlock.sizeof); // Casted
the whole expression. BUT GOT THE WRONG VALUE!!!! Why???
}
char* return_address_right() {
MemoryBlock* local_ptr = cast(MemoryBlock*)ptr;
return cast(char*)local_ptr + MemoryBlock.sizeof; // Now I
first casted the `local_ptr` variable and then added the number
but this time this gave me the right value....
}
extern (C) void main() {
printf("EXPECTED LOCATION: %p\n", ptr + MemoryBlock.sizeof);
printf("RIGHT LOCATION: %p\n", right());
printf("WRONG LOCATION: %p\n", wrong());
printf("RETURNED ADDRESS (wrong): %p\n",
return_address_wrong());
printf("RETURNED ADDRESS (right): %p\n",
return_address_right());
}
```
More information about the Digitalmars-d-learn
mailing list