views:

103

answers:

2

I will use this code as an example:

typedef struct __attribute__((aligned(XXX),packed))
{
   uint16_t type;
   uint32_t id_index;
} a_msg;

void write_func(){
   a_mesg mymsg
   mymsg.type = htons(1);
   mymsg.id_index = htonl(5);
   write(sock_fd, &mymsg, sizeof(a_mesg));
}

void read_func(){
   a_mesg mymsg
   read(sock_fd, &mymsg, sizeof(a_mesg));
   mymsg.type = ntohs(mymsg.type);
   mymsg.id_index = ntohl(mymsg.id_index);     
}

Note: sock_fd is a tcp socket. This is a bit compressed example and would maybe not work but I think you see what I am trying to exemplify (a program that communicates over a binary protocol).

If the application would only run on two 32 bit machines, that communicate with each other through the application, the alignment (aligned(XXX)) would naturally be set to 4. If we communicate in between a 32 bit machine and a 64 bit machine what would the alignment be?

  1. Should XXX be 4 on both 32 and 64 bit machines?
  2. Should XXX be 8 on both 32 and 64 bit machines?
  3. Should XXX be 8 on 64 machines and 4 on 32 bit machines?
  4. XXX is of some other value.

My bet is on alternative 2.

+2  A: 

I would use

#pragma pack 1

on structures. This gives you no padding, which means less net traffic (less bytes to send). Easy casting.

ex:

struct S1 {
   char c1;  // Offset 0, 3 bytes padding
   int i;    // Offset 4, no padding
   char c2;  // Offset 8, 3 bytes padding
};  // sizeof(S1)==12, alignment 4

#pragma pack 1

struct S2 {
   char c1;  // Offset 0, no padding
   int i;    // Offset 1, no padding
   char c2;  // Offset 5, no padding
};  // sizeof(S2)==6, alignment 1
bua
If you're using gcc, you can append `__attribute__((packed))` to each struct member.
detly
Oh wait, they already do that. So why the `pragma`?
detly
Would that be the same as doing __attribute__((aligned(1),packed))
Codeape
Probably yes, but need to find some reference on that.
bua
No, the `aligned` attribute only affects how the structure as a whole must be aligned in memory (i.e. at which multiple of bytes the structure must start). It does not affect the packing/internal alignment of the structure. See http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Type-Attributes.html#Type-Attributes for more info.
Bart van Ingen Schenau
@Bart van Ingen Schenau yes but I also used `packed` attribute in my `__attribute__((aligned(1),packed))`.
Codeape
A: 

I would always used packed structures for any comms protocol. Less scope for confusion, no unecessary overhead, no difficult casting to eliminate the padding at the other end.

Visage
I am already using __attribute__((...,packed)) on the struct.
Codeape