On Tue, 20 May 2008 05:14:57 CST, Martin Bonner <martinfro...@[EMAIL PROTECTED]
>
wrote:
> On May 19, 6:59 pm, nickf3 <nic...@[EMAIL PROTECTED]
> wrote:
> > On May 18, 1:21 am, Martin Bonner <martinfro...@[EMAIL PROTECTED]
> wrote:
> > > On May 17, 9:29 am, nickf3 <nic...@[EMAIL PROTECTED]
> wrote:
> > > > On May 16, 8:27 pm, Alan McKenney <alan_mckenn...@[EMAIL PROTECTED]
>
wrote:
> > > > Please don't reinvent the wheel, use standard library:
> > > > #include <arpa/inet.h>
> > > > uint32_t
> > > > htonl(uint32_t hostlong);
> [etc]
> > > > These are noops on big-endian machines, so there's no overhead.
As I argued in an earlier post, that makes them easy to inadvertently
omit when one develops and tests code on a big endian machine, as I have
found out the hard way (more than once) when ****ting open-source code
developed on a Sparc to an x86.
[ ... ]
> > Let's look at the (open) source, shall we:
> >
> [snip]
> > u_int32_t
> > ntohl(u_int32_t x)
> > {
> > #if BYTE_ORDER == LITTLE_ENDIAN
> > u_char *s = (u_char *)&x;
> > return (u_int32_t)(s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
> > #else
> > return x;
> > #endif
> > }
> >
> > Taken directly from OpenBSD cvs. Looks familiar, doesn't it?
> > Where's that horror you speak of?
[ ... ]
> ... however the real horror is the interface. It takes a u_int32_t in
> and returns a value of the same type. This is plain wrong. Depending
> one which way you are going, the conversion needs to be between a
> u_int32_t and an array of four unsigned char (which can hold an
> octet).
Exactly so.
> [ ... ] sane communications libraries deal in sequences of
> octets stored in unsigned char (which are then packed up in the
> correct order). ntohl is based on an approach where you store bytes
> into the memory of a struct, and then fix-up the byte order. It
> doesn't work if your platform has CHAR_BIT == 64; it requires you to
> control padding between member variables of a struct; it requires you
> to declare the structure with specific-sized members (rather than a
> natural "int" or "long").
Right. It is _never_ a good idea to attempt to overlay a struct (or
a class) on top of a sequence of octets received from (or to be sent
to) a communication interface, as the classic BSD libraries do. Too
many things can go wrong, even when there are only issues with byte
order. It is much more foolproof to represent the content of the
packet/frame/datagram headers in well-designed structs or cl*****
and do the conversions to and from octet sequences explicitly.
C. M. Heard
--
[ See http://www.gotw.ca/resources/clcm.htm
for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


|