Thread overview
Labels in struct
Jan 31, 2015
tcak
Jan 31, 2015
tcak
Jan 31, 2015
Adam D. Ruppe
Jan 31, 2015
Adam D. Ruppe
Jan 31, 2015
zeljkog
Jan 31, 2015
Artur Skawina
January 31, 2015
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.
January 31, 2015
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 ...
January 31, 2015
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"));
}
January 31, 2015
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.)
January 31, 2015
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;
}

January 31, 2015
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