htons, htonl, ntohs, ntohl

Discussion in 'C Programming' started by James Harris, Aug 23, 2013.

  1. The third one is idiomatic; the others are not, even if they likely
    produce the same result.
    That's probably part of why it became the idiomatic form: it dates from
    back before compilers had optimizations like strength reduction.

    Beyond that, byte shuffling is obviously a bitwise operation, not an
    arithmetic one, so bitwise operators seem more appropriate anyway.

    S
     
    Stephen Sprunk, Aug 28, 2013
    #21
    1. Advertisements

  2. James Harris

    Jorgen Grahn Guest

    You mean yourself. Well, it /looked/ like that to me. IMO you should
    have continued in the original thread (possibly changing the subject
    line).

    Even though you did change the topic somewhat, it was still in the
    same area ("foreign" binary data versus C objects), and
    the responses tended to overlap.

    /Jorgen
     
    Jorgen Grahn, Aug 28, 2013
    #22
    1. Advertisements

  3. James Harris

    James Kuyper Guest

    Thunderbird shows me only a single thread on this topic; Google Groups
    agrees. Your message headers indicate that you're using slrn, while
    James Harris' indicate that he's using Microsoft Outlook Express.
    Perhaps it's a difference between the different newsreaders?
     
    James Kuyper, Aug 28, 2013
    #23
  4. James Harris

    James Harris Guest

    No, they were separate threads, and deliberately so. One was about alignment
    and two about different endianness issues. I posted that way because they
    are separate topics. In particular, alignment is not the same as endianness.
    Maybe it's a preference thing. I don't like to see a single thread change
    topic over time. It makes it hard to refer back to. I take Jorgen's point,
    though, that some of the replies could end up overlapping. Though I don't
    agree with his characterisation that one thread was restarted three times!

    James
     
    James Harris, Aug 28, 2013
    #24
  5. James Harris

    Jorgen Grahn Guest

    Yes ... I remember when I used to write x<<3 instead of x*8 when doing
    pure arithmetic, because people said it was faster.
    It can be seen as something else than byte shuffling. You can say
    "a big-endian unsigned 16 bit value is formed by a + 256*b, where a
    and b are in [0..256)" and a lot of people would be comfortable seeing
    it that way.

    Of course a lot of people (including me) are slightly more comfortable
    with shifts ...

    /Jorgen
     
    Jorgen Grahn, Aug 28, 2013
    #25
  6. Back then, it probably was faster. Unfortunately, it didn't always give
    the correct result when applied to negative values, which was a problem.

    Today, I would fail code if bitwise operators are used for arithmetic
    computations; the compiler can be assumed to apply strength reduction
    when/if safe, so it is more important for code to be easily understood
    by its _human_ audience, i.e. the guy who will have to maintain your
    code years in the future.
    Yes, that is technically valid, but I've never seen it presented that
    way before. Shift/or is the accepted idiom, and outside of obfuscated
    code contests, idioms should be preferred.
    Perhaps it's just how I was taught, but bitwise operators are applied to
    strings of bits while arithmetic operators are applied to numbers. Even
    though I know numbers are _represented_ by strings of bits, they are
    completely different conceptual domains to me.

    When I think of moving something from bits 7..0 to bits 15..8, that is a
    bitwise operation, so I use a bitwise operator. Even just reading your
    example with arithmetic operators, it took several seconds for me to
    figure out what you were doing--and it gave me a headache.

    S
     
    Stephen Sprunk, Aug 28, 2013
    #26
  7. James Harris

    Joe Pfeiffer Guest

    OK, your quibble about the difference between a value and its
    representation is noted and you are correct, but I'd be very surprised
    if anybody out there has ever been confused by it.

    If the host computer uses some weird order like you suggest, then the
    routines should do the right thing; in this case, ntohl and htonl
    wouldn't do the same thing any more, and a program that had a
    long-standing bug of using the wrong one would start messing up.
    Program bugs existing but not getting triggered under the existing
    environment is unfortunate, but it happens.

    A story I've told on myself many times is that for many years I thought
    an empty string could be represented by a null pointer -- because I was
    doing all my development on a VAX, and the byte at address 0 was
    user-readable, and happened to contain a 0. When I moved to Sun
    workstations, I had a *lot* of code start getting segfaults. The bugs
    had always been there, they just hadn't been triggered.
    Why? They convert a value on your host into something that can be
    passed to the various functions that need network order, and back.
    Really, once you've got something in network order you should treat it
    as opaque, and convert it back if you want to look at it. I don't see
    any particular advantage to converting to an array of four bytes, and of
    course there is the potential problem of hosts whose byte isn't eight
    bits.
     
    Joe Pfeiffer, Aug 30, 2013
    #27
  8. James Harris

    Jorgen Grahn Guest

    .
    Yes -- if you see 'register' today you assume the code is very old,
    or if it's not, that the programmer is.

    /Jorgen
     
    Jorgen Grahn, Aug 31, 2013
    #28
  9. James Harris

    Jorgen Grahn Guest

    Yes: alignment and endianness problems both have the same solution
    IMO, so I (and others, I think) ended up repeating myself in at least
    two of the threads.
    Right, that was too strongly stated by me. You aimed for clarity.

    /Jorgen
     
    Jorgen Grahn, Aug 31, 2013
    #29
  10. James Harris

    Jorgen Grahn Guest

    I suppose he's saying that if the "various functions that need network
    order" didn't, there would be no need for htons & friends. (And no
    need to remember what's opaque and what's not).

    There's a trap hidden in htons & co: you /do/ need them to handle
    endianness in the BSD socket API ... but they are not suitable for
    handling general endianness issues, because they tend to come together
    with alignment issues. E.g.

    ntohl(*(int*)(buf+n));

    /Jorgen
     
    Jorgen Grahn, Aug 31, 2013
    #30
  11. (snip)
    Yes, don't do that. If there is question about the alignment,
    memcpy() to an appropriately aligned place and ntohl() that.

    But that takes two statements instead of one.

    -- glen
     
    glen herrmannsfeldt, Aug 31, 2013
    #31
  12. James Harris

    Joe Pfeiffer Guest

    You snipped some context from the post I responded to: I thought it was
    pretty clear he was still talking about htons et al.

    I said early in the thread that I regard the fact network order is
    exposed to the user program in the networking API to be a flaw in the
    API. But that's a different question from how htons and friends work.
     
    Joe Pfeiffer, Aug 31, 2013
    #32
  13. James Harris

    Jorgen Grahn Guest

    Yes -- and that's when I prefer not to use ntohl at all.

    /Jorgen
     
    Jorgen Grahn, Aug 31, 2013
    #33
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.