On Monday, 10 July 2017 at 20:13:46 UTC, Adam D. Ruppe wrote:
On Monday, 10 July 2017 at 20:01:39 UTC, FoxyBrown wrote:
Cannot get the offset of static members of a struct

That's because static members do not have an offset. They are not part of the struct in memory, just in name.

We can clearly get a pointer to the static struct X

There's barely any such thing as a static struct. That's just a struct that stands without outside context.... which is almost all structs, actually, so the term isn't special.

since &X.x is effectively the address of X(regardless nomenclature and terminology issues in D trying to hide this).

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.

Just because D obfuscates that static structs have addresses, doesn't mean they don't. No need to perpetuate a misnomer. Static structs and classes have addresses.

No, it might not be officially supported and the compiler may end up doing something funky, but it works, and works as it should, and should become part of D because it is useful:

auto GetOpts(T)(string[] args)
{       
        import std.getopt, std.meta, std.traits;
        auto t = GetStaticAddress!(T)();
        
        string combine()
        {
                string s = "";
                foreach(m; AliasSeq!(__traits(allMembers, T)))
                {
                        mixin("enum a = __traits(getAttributes, T."~m~")[0];");
                        mixin("s ~= \"`"~a~"`, &"~T.stringof~"."~m~", \";");
                }
                return s;
        }

        enum s = combine();
        mixin("return getopt(args, "~s~");");
}

struct X
{
        align(1):
        __gshared public static:
                @("A") bool A;
                @("B") string B;      
                @("C") string[] C;
};


which allows us to do

GetOps!X(args)

vs

getop(args, "A", &X.A, "B", &X.B, "C", &X.C);


replaces the overly verbose getopt. Tell me that isn't useful and tell me that static structs don't have addresses!



Reply via email to