On 7/11/2017 6:14 AM, FoxyBrown wrote:
On Monday, 10 July 2017 at 20:13:46 UTC, Adam D. Ruppe wrote:
No, it isn't. Static members are stored in an entirely different place
than non-static members. They are really just global variables in
memory with their in-source name being nested somewhere else.
This is not true, just because there isn't any official statement, or
even if denied, does not make it true. I have proof:
auto GetStaticAddress(T)()
{
mixin("auto p = cast(T*)&T."~__traits(allMembers, T)[0]~";");
return p;
}
Returns the address of a struct's static members.
It's pretty obvious, the compiler seems to instantiate the static
members simply as a sort of "singleton". They are laid out with the same
relative offsets as the struct(which is obvious, as that is the most
natural way). That is all that is needed to treat the memory the static
variables use as the struct in which they are part of. No need to make
it any more complex than that.
Every variable has an address. That includes static members of a struct.
But their location has absolutely no relationship to any instance of a
struct. They have a fixed location in memory. Consider:
module Foo;
int x;
struct Bar {
static int y;
int z;
}
There is effectively no difference between x and y here. The only
difference is that Bar is part of y's namespace, so you can access them
like so:
Foo.x;
Foo.Bar.y;
y's location has no relationship to any instance of Bar, and the
declaration of the Bar type has no address. Of course you can take the
address of y, as &Bar.y, but you can also take the address of x. Take y
out of Bar and the only difference is that you no longer need Bar as
part of the namespace. On the other hand:
Bar b;
writeln(b.z);
As an instance of Bar, b *does* have a location in memory. And z *does*
have an offset that is relative to that location.
So y.offsetof does not exist, because there is no instance of Bar to
which it can have a relative address.