Structs can't be zero bytes in size?

Dylan Knutson tcdknutson at gmail.com
Mon Sep 2 16:57:55 PDT 2013


Take a look at this:

http://dpaste.dzfl.pl/6bf578a3

```
struct Foo {}
pragma(msg, Foo.sizeof);
void main() {}
```

output: 1LU

It seems like structs can't have a size of zero, but this doesn't 
make a whole lot of sense semantically. I've currently got a 
project using `std.variant : Algebraic`, so a struct which simply 
acts as a distinct type would be useful to have.

Take, for example, a simple client-server payload passing 
implementation:

```
enum PayloadType {
		response_success,
		response_failure
}
alias Payload = Algebraic!(
	ResponseSuccess,
	ResponseFailure);

struct ResponseSuccess {
	static type = PayloadType.response_success;
}

struct ResponseFailure {
	static type = PayloadType.response_failure;

	uint code;
}


// Then pseudocode for how the structure is sent over a connection
void sendPayload(Resp)(Resp response, OutputStream conn) {
	conn.write(Resp.type);

	static if(Resp.sizeof) {
		// Always triggered, even for empty structs.
		conn.write(response);
	}
}

// And how it's recieved from a connection
Payload recievePayload(InputStream conn) {
	PayloadType type = conn.read!PayloadType();

	Payload ret;

	final switch(type) with(PayloadType) {
		case response_success:
			// Nothing actually needs to be read from the stream,
			// but 1 byte extra is written anyways because ResponseSuccess 
is 1 byte.
			ubyte throwaway = conn.read!ubyte();

			ret = ResponseSuccess();
			break;

		case response_failure:
			ResponseFailure failure = conn.read!ResponseFailure();
			ret = failure;
			break;
	}

	return ret;

}

// Usage:
auto conn = new InputOutputStream(); //Responds to .read() and 
.write()
conn.sendPayload(ReponseSuccess());

conn.recievePayload().visit!(
	(ResponseSuccess resp) {
		writeln("Success!");
	},
	(ResponseFailure resp) {
		writeln("Failure! Code: ", resp.code);
	}
)()
```

In the above example, if ResponseSuccess had a size of zero, 
there would be no additional network overhead. However, because 
the extra byte of `response` is written to the stream, one must 
read an empty byte on the recieving end, and throw it away. In 
this case, it accounts for 33% of the network overhead for 
transferring a ResponseSuccess structure. 2 bytes for the type of 
struct, and then 1 additional empty byte... just because. Not to 
mention that it's not intuitive with how structures normally 
work. According to individuals in the IRC channel, this is 
probably due to the implicit void in structs. Can someone shed 
some light on this?


More information about the Digitalmars-d mailing list