On Wednesday, 16 June 2021 at 23:20:26 UTC, Ali Çehreli wrote:
>Thank you, both. It still rules out an address at "compile time" in general. For example, we cannot use such an address when instantiating a template, or static array length, etc.
And if I understand it correctly, there must be a pointer variable for the linker to initialize. Fine then: That's how this usage works for C but not for D. :)
Thank you,
Ali
Yes, there must be a pointer variable, which explains why we can not do compile time pointer arithmetic, which is fair and square (although I think it might be possible with some extra compiler effort). It does not explain why we can't take addresses of struct members, though, since we have a pointer variable there!
Coming back to the working part of my first example:
struct Foo{
int bar;
}
__gshared Foo foo;
void *fooptr = &foo;
This works! And yields very similar relocations than the C version (plus some overhead and name-mangling):
[...]
0000000000000000 w O .data._D19TypeInfo_S4test3Foo6__initZ 0000000000000091 _D19TypeInfo_S4test3Foo6__initZ
0000000000000000 g O .bss 0000000000000004 _D4test3Foo6__initZ
0000000000000004 g O .bss 0000000000000004 _D4test3fooSQk3Foo
0000000000000000 g .tdata. 0000000000000008 _D4test6fooptrPv
0000000000000000 g O .rodata 000000000000000d _D4test12__ModuleInfoZ
[...]
RELOCATION RECORDS FOR [.tdata.]:
OFFSET TYPE VALUE
0000000000000000 R_X86_64_64 _D4test3fooSQk3Foo
[...]
The only difference is that the compiler will not pass down relocations plus an offset (i.e. relocating to a member of a struct) down to the linker, and I don't quite see a specific reason why it should not.