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());
}
```


Reply via email to