Re: Bytes' order with different C++ compilers
  Home FAQ Contact Sign in
comp.lang.c++.moderated only
 
Advanced search
POPULAR GROUPS

more...

 Up
Re: Bytes' order with different C++ compilers         

Group: comp.lang.c++.moderated · Group Profile
Author: nickf3
Date: May 19, 2008 10:00

On May 18, 1:21 am, Martin Bonner yahoo.co.uk> wrote:
> On May 17, 9:29 am, nickf3 gmail.com> wrote:
>
>> On May 16, 8:27 pm, Alan McKenney yahoo.com> wrote:
...
>
>>> A. // only works if host is big-endian
>
>>> unsigned char *buf = ....
>>> unsigned long uint32value;
>
>>> memcpy( &uint32value, buf+ipos, 4 );
>
>>> B. // works regardles of endianness of your host
>
>>> uint32value = ( buf[ipos] << 24 ) |
>>> ( buf[ipos+1] << 16 ) |
>>> ( buf[ipos+2] << 8 ) |
>>> buf[ipos+3] ;
>
>>> I generally use B, to avoid having to worry
>>> about endianness.
>
>> Please don't reinvent the wheel, use standard library:
>
>> #include
>
>> uint32_t
>> htonl(uint32_t hostlong);
>
>> uint16_t
>> htons(uint16_t hostshort);
>
>> uint32_t
>> ntohl(uint32_t netlong);
>
>> uint16_t
>> ntohs(uint16_t netshort);
>
>> These are noops on big-endian machines, so there's no overhead.
>
> Except that they are /not/ part of the standard library unless you can
> assume Posix. Also they have a horrible interface. The code Alan
> wrote took a buffer of unsigned chars (presumably containing octets
> from the communications protocol) and converted it to a long in a way
> that will work on any compiler that implements the C++ standard (and a
> fair few that don't). ntohl et-al assumes all sorts of things about
> the representations (which may not be true, eg, on a DSP)
>

Let's look at the (open) source, shall we:

/* $OpenBSD: ntohl.c,v 1.6 2005/08/06 20:30:03 espie Exp $ */
/*
* Written by J.T. Conklin netbsd.org>.
* Public domain.
*/

#include
#include

#undef ntohl

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?
Then, there's arch-specific code for i386:

... BSD license

/* hostorder = ntohl(netorder) */
ENTRY(ntohl)
movl 4(%%esp),%%eax
rorw $8,%%ax
roll $16,%%eax
rorw $8,%%ax
ret

Then, sparc:

... BSD license

/* hostorder = ntohl(netorder) */
ENTRY(ntohl)
retl
nop

And many other archs.

It's perfectly fine (I'd say, required) to _understand_
how to write portable code, but would you want every
programmer on your team doing this stuff by hand, or
would you want them _reusing_ the existing libs?

Yes, it's not a part of the C++ std lib, but neither is that
socket API you use to get to the "communication channel", nor
whatever API you use to talk to a DSP (which doesn't have
C interface, only C++, right?)

Unless you elaborate on that last statement in
your post, I call it FUD.

--
Nikolai

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
no comments
diggit! del.icio.us! reddit!