Re: Putting an int value in a char array

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Vlad Dogaru

    Re: Putting an int value in a char array

    On May 2, 7:52 pm, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
    memcpy(&char_bu f, &int_var, sizeof int_var);
    [snip]
    The shifting method (used on unsigned types) can give you
    a portable solution.
    Would memcpy and htons & co be a correct approach? My problem is that
    it's not only short ints that I have to accomodate, but also the
    occasional long; I'd like to have a uniform handling of these
    operations.

    Also, I'm not sure if the way I found to "deserializ e" these values is
    safe and recommended:

    x = htons(x);
    memcpy(&buffer, &x, sizeof x);
    /* Later, at the other end: */
    x = ntohs(*((unsign ed short *) buffer));

    I only need unsigned values, so unsigned {short, long} should be
    enough. And one final question: would there be any reason to using
    uint16_t and uint32_t instead of unsigned short and unsigned long?

    Thanks and sorry for the question avalanche,
    Vlad
  • Ben Bacarisse

    #2
    Re: Putting an int value in a char array

    Vlad Dogaru <ddvlad@gmail.c omwrites:
    On May 2, 7:52 pm, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
    > memcpy(&char_bu f, &int_var, sizeof int_var);
    >[snip]
    >The shifting method (used on unsigned types) can give you
    >a portable solution.
    >
    Would memcpy and htons & co be a correct approach?
    First htons and htnol (the "long" version) are POSIX, so technically
    off topic here. They are an excellent choice for this problem but
    they incur a cost that can be avoided if you are designing a system
    for CPUs where the "host" representation is different to the "network"
    one. If you can use you own functions, you can avoid this (probably
    small) cost by making these operations "null" on your main platform.
    My problem is that
    it's not only short ints that I have to accomodate, but also the
    occasional long; I'd like to have a uniform handling of these
    operations.
    Then there is htonl and ntohl that take uint32_t values. Note that C
    does not insist that long is 32 bits, but uint32_t is.
    Also, I'm not sure if the way I found to "deserializ e" these values is
    safe and recommended:
    >
    x = htons(x);
    memcpy(&buffer, &x, sizeof x);
    That is the safe, portable, way. However, a lot of code will be able
    to define the buffer as struct with integer members, so one often
    sees:

    msg.data1 = htons(x);

    or even, the more dangerous:

    *(uint16_t *)buffer = htons(x);

    The memcpy version avoids any alignment problems and so it more portable.
    /* Later, at the other end: */
    x = ntohs(*((unsign ed short *) buffer));
    The reverse would have been

    memcpy(&x, &buffer, sizeof x);
    x = htons(x);

    but the dangerous cast is often used. Data formats in protocols are
    often chosen so that there will be no alignment problems on most
    common processors, so you will have to decide between portability,
    code clarity and speed of packing knowing what you know about the
    target systems and the purpose of the code.
    I only need unsigned values, so unsigned {short, long} should be
    enough. And one final question: would there be any reason to using
    uint16_t and uint32_t instead of unsigned short and unsigned long?
    Yes. The most important is that POSIX now defines the [nh]to[hn][ls]
    functions in terms of these types. These days, you are more likely
    to find a system where short 16 bits or long 32 bits than you are
    to find one where uint32_t is either not defined or is hard to define
    yourself.

    --
    Ben.

    Comment

    • Vlad Dogaru

      #3
      Re: Putting an int value in a char array

      On May 3, 5:01 pm, Ben Bacarisse <ben.use...@bsb .me.ukwrote:
      Yes. The most important is that POSIX now defines the [nh]to[hn][ls]
      functions in terms of these types. These days, you are more likely
      to find a system where short 16 bits or long 32 bits than you are
      to find one where uint32_t is either not defined or is hard to define
      yourself.
      Thank you for all your time, Ben.

      Vlad

      Comment

      Working...