Messages in this thread | | | From | Olaf Titz <> | Subject | Re: Off-topic | Date | 06 Mar 1997 11:05:31 +0100 |
| |
Richard B. Johnson <root@analogic.com> wrote: > struct foo { > short int one __attribute__((packed)); > long int two __attribute__((packed)); > } FOO; > This returns a length of 6 which is what I want. Bare bones, left to > gcc's whim, it would return a value of 8 as it quietly aligns the > longword on a longword boundary. This IS what most people want. However, > when you are dealing with a serial data-stream, you have to take what > you get. Of course, you could pretend that the serial data stream was > a string of bytes, then initialize various kinds of pointers to > point to various data-elements. That is kind of hokey.
I do the latter thing, because I don't want to depend on gcc (or rather have to use machines where gcc isn't available). Here is a SOCKS request structure from this POV: #define rq_ver(s) ((s)->buf[0]) #define rq_cmd(s) ((s)->buf[1]) #define rq_rsv(s) ((s)->buf[2]) #define rq_atyp(s) ((s)->buf[3]) #define rq_addr(s) (*(struct in_addr *)(((s)->buf)+4)) #define rq_port(s) (*(unsigned short *)(((s)->buf)+8))
where s is a pointer to a struct which contains unsigned char buf[BUFS];
The code gets rather readable this way.
Beware - both __attribute__((packed)) and this method don't account for hardware enforced alignment. If it is ever compiled on a system that requires 8-byte alignment for a struct in_addr (a 4-byte entity) it will bomb. I don't know if there is such hardware, but I have already got bus errors on an HP using this technique on a misaligned short (with the same program). A way around that is something like
#define xx(s) ((((s)->buf[5])<<8)+(s)->buf[6])
if xx is an unsigned short in network order on position 5.
olaf
| |