Why no offsetof for static struct?

FoxyBrown via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Jul 10 14:14:54 PDT 2017


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!





More information about the Digitalmars-d-learn mailing list