www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why no offsetof for static struct?

Cannot get the offset of static members of a struct

struct X
{
     __gshared public:
         int x;
}


X.x.offsetof < invalid.

We can clearly get a pointer to the static struct X since &X.x is 
effectively the address of X(regardless nomenclature and 
terminology issues in D trying to hide this).

e.g.,

auto p = cast(X*)&X.x;

will, for all practical purposes be a pointer to X.


auto GetStaticAddress(T)()
{
	mixin("auto p = cast(T*)&T."~__traits(allMembers, T)[0]~";");
	return p;
}

Of course, assuming that the first member is at the same location 
as the start of the struct and the elements are laid out in the 
same positions(not sure if this is guaranteed, but probably is).

Would be much nicer if we could just take the address of a static 
struct



This is pretty useful for simplification:

auto GetStaticAddress(T)()
{
	mixin("auto p = cast(T*)&T."~__traits(allMembers, T)[0]~";");
	return p;
}

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);


Could be improved to only deal with special argument attributes 
on X's fields and allow for non-static strucs(for the general 
case of mapping). Sort of a map between attribute space on a type 
and some function.
Jul 10 2017