On 09/15/2014 02:31 PM, Hei Chan wrote: > > > On Monday, September 15, 2014 9:21 PM, Andrew Haley <aph@xxxxxxxxxx> wrote: > On 09/15/2014 12:57 PM, Hei Chan wrote: >> // on a big-endian 64-bit machine >> >> struct Message { >> int32_t a; >> int16_t b; >> char c; >> char padding; >> }; >> >> // send over a socket >> Message msg = {12345, 678, 'x', 0}; > > I'd do this: > > Message msg = {htonl(12345), htons(678), 'x', 0}; > > What if I have no control of the sender? I don't understand this question. You said that you were sending. >> send(fd, &msg, sizeof Message, 0); >> >> >> // another machine: a little-endian 64-bit machine >> char buffer[1024]; >> if (recv(fd, buffer, sizeof buffer, 0)) { >> Message msg; >> // or we can use the union trick > > Why not read into the Message? > > I think it goes back to the same issue as Andy (the original poster) > -- the server/sender will send multiple kinds of message types. > > For instances, > > enum class MsgType : int32_t { > Heartbeat, > Logon, > Logout > }; > > struct Header { > int32_t MsgType; > int32_t padding; > } > > struct LogonBody { > int32_t a; > int16_t b; > char c; > char padding; > } > > I can read into an instance of Header first (1 system call), then I > know the message type so I can read into an instance of LogonBody > (another system call). But my goal is to avoid latency. I > certainly would prefer 1 system call instead of 2 if possible. But you can either read into a union of the message types and handle that, or read into a byte array and pick the data straight from there. Like this: int byteswap (int u) { return ((((u) & 0xff000000) >> 24) | (((u) & 0x00ff0000) >> 8) | (((u) & 0x0000ff00) << 8) | (((u) & 0x000000ff) << 24)); } int readInt(char *a) { int val; memcpy(&val, a, sizeof val); return byteswap(val); } which generates this: readInt: ldr w0, [x0] rev w0, w0 ret > Hope now it makes sense to you. Not really, no. I know that there are many bad ways of solving the problem. All I'm saying is that you don't have to do it in a bad way. C provides you with everything you need to do it well. If you want a way to read from an arbitrary position in an byte array into any type, in any endianness, you can do that; see readInt above. If you want to read into a union of all message types, you can do that. Andrew.