www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Labels in struct

reply "tcak" <tcak gmail.com> writes:
I do not have a big example in the end to show, but is there any 
way to put labels into struct definitions?

struct CommunicationMessage{
     char[2] signature;

mainData:
     int info1;
     int info2;

extraData:
     ushort checksum;

content:
}


Example I defined something like above. I am using it as a base 
structure, and don't know how long the content of message will 
be. But I know that it will be at the end. I could use that 
"content" label to find out about end of struct. But 
unfortunately, it doesn't seem like it is supported.

I could say "void* endOfStruct = &struct + sizeof(struct)", but 
then struct wouldn't be self explanatory with that content label 
at the end.
Jan 31 2015
next sibling parent "tcak" <tcak gmail.com> writes:
On Saturday, 31 January 2015 at 16:04:36 UTC, tcak wrote:
 I do not have a big example in the end to show, but is there 
 any way to put labels into struct definitions?

 struct CommunicationMessage{
     char[2] signature;

 mainData:
     int info1;
     int info2;

 extraData:
     ushort checksum;

 content:
 }


 Example I defined something like above. I am using it as a base 
 structure, and don't know how long the content of message will 
 be. But I know that it will be at the end. I could use that 
 "content" label to find out about end of struct. But 
 unfortunately, it doesn't seem like it is supported.

 I could say "void* endOfStruct = &struct + sizeof(struct)", but 
 then struct wouldn't be self explanatory with that content 
 label at the end.
... **without** that content label ...
Jan 31 2015
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
You could use a UDA like that, though getting the offset will be 
a bit tricky.


The idea is to use some uda type, even plain string is good 
enough, then use the __traits to find the first appearance of 
that UDA in the object and return that offset.

Keep in mind that the  uda: syntax applies it to ALL following 
members, it isn't really a label, but if we only look at the 
first time it shows up we can kinda pretend it is one.

Here's an example:


struct Foo {
	int b;
	 ("label_one"): // offset 4
	int c;
	int d;
	 ("label_two"): // offset 12
	int e;
}

// get the offset of the label on a type, see below for usage
size_t offsetOf(T, string label)() {
	foreach(memberName; __traits(allMembers, T)) {
		foreach(attribute; __traits(getAttributes, __traits(getMember, 
T, memberName))) {
			static if(is(typeof(attribute) == string) && attribute == 
label)
				return __traits(getMember, T, memberName).offsetof;
		}
	}

	assert(0, "no such label");
}

void main() {
        // gives what we expect
	pragma(msg, offsetOf!(Foo, "label_one"));
	pragma(msg, offsetOf!(Foo, "label_two"));
}
Jan 31 2015
parent "Adam D. Ruppe" <destructionator gmail.com> writes:
Oh this hack also won't work with a label at the very end. You 
could use sizeof for that though (however that would include 
padding bytes. Perhaps last member's offsetof plus last member's 
sizeof is a bit more accurate.)
Jan 31 2015
prev sibling next sibling parent zeljkog <zeljkog home.com> writes:
On 31.01.15 17:04, tcak wrote:
 I do not have a big example in the end to show, but is there any way to
 put labels into struct definitions?

 struct CommunicationMessage{
      char[2] signature;

 mainData:
      int info1;
      int info2;

 extraData:
      ushort checksum;

 content:
 }
Members of type struct are actualy labels. struct CommunicationMessage{ struct Md { int info1; int info2; }; struct Ed { ushort checksum; } struct Cnt { } char[2] signature; Md mainData; Ed extraData; Cnt content; }
Jan 31 2015
prev sibling parent Artur Skawina via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On 01/31/15 17:04, tcak via Digitalmars-d-learn wrote:
 
 struct CommunicationMessage{
[...]
 content:
 }
 
 
 Example I defined something like above. I am using it as a base structure, and
don't know how long the content of message will be. But I know that it will be
at the end. I could use that "content" label to find out about end of struct.
But unfortunately, it doesn't seem like it is supported.
 
 I could say "void* endOfStruct = &struct + sizeof(struct)", but then struct
wouldn't be self explanatory with that content label at the end.
The traditional way (ie C-like) would be ubyte[0] content; // zero-sized; use casts etc to access data. as the last member. D supports that too, and just like many other D features it works for ~80% of cases. IOW you should be able to get it to work, but you might run into problems if you need to access/manipulate such types. artur
Jan 31 2015