How to extract bytes from a long?

Discussion in 'C Programming' started by Curt Geske, Oct 15, 2003.

  1. Curt Geske

    Curt Geske Guest

    I'm suprised no one suggested a union!

    #include <stdio.h>
    union _x
    {
    long lng;
    char byt[4];
    } X;

    void main( void )
    {
    int i; // Always need an 'i', ...
    long val = 0x12345678;

    X.lng = val;
    for( i = 3; i >= 0; i-- )
    {
    printf( "%#02x\n", X.byt );
    }


    } // main
     
    Curt Geske, Oct 15, 2003
    #1
    1. Advertising

  2. Curt Geske

    Chris Dollin Guest

    Curt Geske wrote:

    > I'm suprised no one suggested a union!
    >
    > #include <stdio.h>
    > union _x
    > {
    > long lng;
    > char byt[4];
    > } X;
    >
    > void main( void )
    > {
    > int i; // Always need an 'i', ...
    > long val = 0x12345678;
    >
    > X.lng = val;
    > for( i = 3; i >= 0; i-- )
    > {
    > printf( "%#02x\n", X.byt );
    > }
    >
    >
    > } // main


    We wanted solutions that didn't exhibit undefined behaviour, ta very
    much. Or even unspecified behaviour - like, is X.byt[0] 0x12 or 0x78
    or 0x34 or 0x56, and why?

    --
    Chris "electric hedgehog" Dollin
    C FAQs at: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.c.html
    C welcome: http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html
     
    Chris Dollin, Oct 15, 2003
    #2
    1. Advertising

  3. Curt Geske <> wrote:

    If you want to reply to a post, please use the "Reply" function of your
    newsreader and do not start a new thread. Thank you.

    >I'm suprised no one suggested a union!
    >
    >#include <stdio.h>
    > union _x
    > {
    > long lng;
    > char byt[4];


    Stop right here: what makes you think a long is four chars wide?

    <SNIP>

    Regards
    --
    Irrwahn
    ()
     
    Irrwahn Grausewitz, Oct 15, 2003
    #3
  4. Curt Geske

    Serve La Guest

    "Irrwahn Grausewitz" <> wrote in message
    news:...
    > >I'm suprised no one suggested a union!
    > >
    > >#include <stdio.h>
    > > union _x
    > > {
    > > long lng;
    > > char byt[4];

    >
    > Stop right here: what makes you think a long is four chars wide?


    That could be easily overcome with sizeof. It's more that you can't rely on
    the byte order if you try to do it portably.
     
    Serve La, Oct 15, 2003
    #4
  5. Curt Geske

    David Rubin Guest

    Serve La wrote:
    >
    > "Irrwahn Grausewitz" <> wrote in message
    > news:...
    > > >I'm suprised no one suggested a union!
    > > >
    > > >#include <stdio.h>
    > > > union _x
    > > > {
    > > > long lng;
    > > > char byt[4];

    > >
    > > Stop right here: what makes you think a long is four chars wide?

    >
    > That could be easily overcome with sizeof. It's more that you can't rely on
    > the byte order if you try to do it portably.


    No, the problem is that you can't write into one union field and read
    from another.

    /david

    --
    Andre, a simple peasant, had only one thing on his mind as he crept
    along the East wall: 'Andre, creep... Andre, creep... Andre, creep.'
    -- unknown
     
    David Rubin, Oct 15, 2003
    #5
  6. Curt Geske wrote:

    > I'm suprised no one suggested a union!


    Since your suggestion involves non-portable implementation-defined behavior
    (in addition to the obvious illiteracy for the return type for main), I'm
    surprised that anyone would suggest it.

    >
    > #include <stdio.h>
    > union _x
    > {
    > long lng;
    > char byt[4];
    > } X;
    >
    > void main( void )


    I'm surprised you have the gall to write the above line. Please wake up.
    Your nap is now at least 14 years long.

    > {
    > int i; // Always need an 'i', ...
    > long val = 0x12345678;
    >
    > X.lng = val;
    > for( i = 3; i >= 0; i-- )
    > {
    > printf( "%#02x\n", X.byt );
    > }


    Try the following on for size. Not that "the most recent store" was to the
    '.lng' member, which is different from the '.byt' member.

    [#5] With one exception, if the value of a member of a union
    object is used when the most recent store to the object was
    to a different member, the behavior is
    implementation-defined.70) One special guarantee is made in
    order to simplify the use of unions: If a union contains
    several structures that share a common initial sequence (see
    below), and if the union object currently contains one of
    these structures, it is permitted to inspect the common
    initial part of any of them anywhere that a declaration of
    the completed type of the union is visible. Two structures
    share a common initial sequence if corresponding members
    have compatible types (and, for bit-fields, the same widths)
    for a sequence of one or more initial members.



    >
    >
    > } // main



    --
    Martin Ambuhl
     
    Martin Ambuhl, Oct 15, 2003
    #6
  7. Curt Geske

    cody Guest

    > >#include <stdio.h>
    > > union _x
    > > {
    > > long lng;
    > > char byt[4];

    >
    > Stop right here: what makes you think a long is four chars wide?


    #include <stdio.h>
    union _x
    {
    long lng;
    char byt[sizeof long];
    }

    better?

    --
    cody

    [Freeware, Games and Humor]
    www.deutronium.de.vu || www.deutronium.tk
     
    cody, Oct 15, 2003
    #7
  8. Curt Geske

    Eric Sosman Guest

    cody wrote:
    >
    > > >#include <stdio.h>
    > > > union _x
    > > > {
    > > > long lng;
    > > > char byt[4];

    > >
    > > Stop right here: what makes you think a long is four chars wide?

    >
    > #include <stdio.h>
    > union _x
    > {
    > long lng;
    > char byt[sizeof long];
    > }
    >
    > better?


    Marginally. It still doesn't address the issue raised
    by both David Rubin and Martin Ambuhl, and it still uses
    an identifier reserved for the implementation, and it still
    risks trouble with trap representations or if the system
    uses signed magnitude or ones' complement arithmetic ...

    ... but other than that, Mrs. Lincoln, how did you
    like the play?

    --
     
    Eric Sosman, Oct 15, 2003
    #8
  9. Curt Geske

    cody Guest

    > > > >I'm suprised no one suggested a union!
    > > > >
    > > > >#include <stdio.h>
    > > > > union _x
    > > > > {
    > > > > long lng;
    > > > > char byt[4];
    > > >
    > > > Stop right here: what makes you think a long is four chars wide?

    > >
    > > That could be easily overcome with sizeof. It's more that you can't rely

    on
    > > the byte order if you try to do it portably.

    >
    > No, the problem is that you can't write into one union field and read
    > from another.



    Isn't that what a union is good for???

    --
    cody

    [Freeware, Games and Humor]
    www.deutronium.de.vu || www.deutronium.tk
     
    cody, Oct 15, 2003
    #9
  10. In article <bmkgv9$npurr$-berlin.de>,
    "cody" <> wrote:

    > > > > >I'm suprised no one suggested a union!
    > > > > >
    > > > > >#include <stdio.h>
    > > > > > union _x
    > > > > > {
    > > > > > long lng;
    > > > > > char byt[4];
    > > > >
    > > > > Stop right here: what makes you think a long is four chars wide?
    > > >
    > > > That could be easily overcome with sizeof. It's more that you can't rely

    > on
    > > > the byte order if you try to do it portably.

    > >
    > > No, the problem is that you can't write into one union field and read
    > > from another.

    >
    >
    > Isn't that what a union is good for???


    Stay with freeware. Don't even think about getting a paid job as a
    programmer.
     
    Christian Bau, Oct 15, 2003
    #10
  11. Curt Geske

    cody Guest

    "David Rubin" <> schrieb im Newsbeitrag
    news:...
    > Serve La wrote:
    > >
    > > "Irrwahn Grausewitz" <> wrote in message
    > > news:...
    > > > >I'm suprised no one suggested a union!
    > > > >
    > > > >#include <stdio.h>
    > > > > union _x
    > > > > {
    > > > > long lng;
    > > > > char byt[4];
    > > >
    > > > Stop right here: what makes you think a long is four chars wide?

    > >
    > > That could be easily overcome with sizeof. It's more that you can't rely

    on
    > > the byte order if you try to do it portably.

    >
    > No, the problem is that you can't write into one union field and read
    > from another.


    With one exception, which is valid in this case:

    [#5] With one exception, if the value of a member of a union
    object is used when the most recent store to the object was
    to a different member, the behavior is
    implementation-defined.70)

    <<< look here below! >>>
    One special guarantee is made in
    order to simplify the use of unions: If a union contains
    several structures that share a common initial sequence (see
    below), and if the union object currently contains one of
    these structures, it is permitted to inspect the common
    initial part of any of them anywhere that a declaration of
    the completed type of the union is visible. Two structures
    share a common initial sequence if corresponding members
    have compatible types (and, for bit-fields, the same widths)
    for a sequence of one or more initial members.

    --
    cody

    [Freeware, Games and Humor]
    www.deutronium.de.vu || www.deutronium.tk
     
    cody, Oct 15, 2003
    #11
  12. Eric Sosman wrote:
    > cody wrote:
    >>
    >> > >#include <stdio.h>
    >> > > union _x
    >> > > {
    >> > > long lng;
    >> > > char byt[4];
    >> >
    >> > Stop right here: what makes you think a long is four chars wide?

    >>
    >> #include <stdio.h>
    >> union _x
    >> {
    >> long lng;
    >> char byt[sizeof long];
    >> }
    >>
    >> better?

    >
    > Marginally. It still doesn't address the issue raised
    > by both David Rubin and Martin Ambuhl, and it still uses
    > an identifier reserved for the implementation, and it still
    > risks trouble with trap representations or if the system
    > uses signed magnitude or ones' complement arithmetic ...


    For completeness, there's also a syntax error.

    Jeremy.
     
    Jeremy Yallop, Oct 15, 2003
    #12
  13. Curt Geske

    cody Guest

    > > #include <stdio.h>
    > > union _x
    > > {
    > > long lng;
    > > char byt[sizeof long];
    > > }
    > >
    > > better?

    >
    > Marginally. It still doesn't address the issue raised
    > by both David Rubin and Martin Ambuhl, and it still uses
    > an identifier reserved for the implementation,


    What reserved identifier? Do you mean the underscore before x?

    > and it still
    > risks trouble with trap representations or if the system
    > uses signed magnitude or ones' complement arithmetic ...


    He just wanted to extract the bytes of a long. Sometimes you do not care how
    the
    bytes are represented are in that long, just getting them is enough.

    You should not assign new values to byt, that could cause trap
    representations as you said, but reading is allowed and safe.

    > ... but other than that, Mrs. Lincoln, how did you
    > like the play?


    What do you mean with that?

    --
    cody

    [Freeware, Games and Humor]
    www.deutronium.de.vu || www.deutronium.tk
     
    cody, Oct 15, 2003
    #13
  14. Curt Geske

    cody Guest

    > >> #include <stdio.h>
    > >> union _x
    > >> {
    > >> long lng;
    > >> char byt[sizeof long];
    > >> }
    > >>
    > >> better?

    > >
    > > Marginally. It still doesn't address the issue raised
    > > by both David Rubin and Martin Ambuhl, and it still uses
    > > an identifier reserved for the implementation, and it still
    > > risks trouble with trap representations or if the system
    > > uses signed magnitude or ones' complement arithmetic ...

    >
    > For completeness, there's also a syntax error.



    The missing semicolon at the end?

    --
    cody

    [Freeware, Games and Humor]
    www.deutronium.de.vu || www.deutronium.tk
     
    cody, Oct 15, 2003
    #14
  15. "cody" <> wrote:

    >"David Rubin" <> schrieb im Newsbeitrag
    >news:...
    >> Serve La wrote:
    >> >
    >> > "Irrwahn Grausewitz" <> wrote in message
    >> > news:...
    >> > > >I'm suprised no one suggested a union!
    >> > > >
    >> > > >#include <stdio.h>
    >> > > > union _x
    >> > > > {
    >> > > > long lng;
    >> > > > char byt[4];
    >> > >
    >> > > Stop right here: what makes you think a long is four chars wide?
    >> >
    >> > That could be easily overcome with sizeof. It's more that you can't rely

    >on
    >> > the byte order if you try to do it portably.

    >>
    >> No, the problem is that you can't write into one union field and read
    >> from another.

    >
    >With one exception, which is valid in this case:


    What makes you think so? Implementation defined means "not portable"
    and there are no structs in the union, so why should ISO/IEC 9899:1999
    6.5.2.3#5 be applicable in this case?

    BTW, you should name version, chapter & verse if you quote a standard
    (or a draft version of it, like you did).

    <6.5.2.3#5 snipped>

    Regards
    --
    Irrwahn
    ()
     
    Irrwahn Grausewitz, Oct 16, 2003
    #15
  16. "cody" <> wrote:

    >> >> #include <stdio.h>
    >> >> union _x
    >> >> {
    >> >> long lng;
    >> >> char byt[sizeof long];
    >> >> }
    >> >>
    >> >> better?
    >> >
    >> > Marginally. It still doesn't address the issue raised
    >> > by both David Rubin and Martin Ambuhl, and it still uses
    >> > an identifier reserved for the implementation, and it still
    >> > risks trouble with trap representations or if the system
    >> > uses signed magnitude or ones' complement arithmetic ...

    >>
    >> For completeness, there's also a syntax error.

    >
    >The missing semicolon at the end?


    Actually, there are two syntax errors, of which the
    missing semicolon is one.
    --
    Irrwahn
    ()
     
    Irrwahn Grausewitz, Oct 16, 2003
    #16
  17. cody wrote:

    >> >> #include <stdio.h>
    >> >> union _x
    >> >> {
    >> >> long lng;
    >> >> char byt[sizeof long];
    >> >> }
    >> >>
    >> >> better?
    >> >
    >> > Marginally. It still doesn't address the issue raised
    >> > by both David Rubin and Martin Ambuhl, and it still uses
    >> > an identifier reserved for the implementation, and it still
    >> > risks trouble with trap representations or if the system
    >> > uses signed magnitude or ones' complement arithmetic ...

    >>
    >> For completeness, there's also a syntax error.

    >
    >
    > The missing semicolon at the end?


    That's one. There's another.

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Oct 16, 2003
    #17
  18. Curt Geske

    Mark Gordon Guest

    On Thu, 16 Oct 2003 00:41:46 +0200
    "cody" <> wrote:

    > > > #include <stdio.h>
    > > > union _x
    > > > {
    > > > long lng;
    > > > char byt[sizeof long];
    > > > }
    > > >
    > > > better?

    > >
    > > Marginally. It still doesn't address the issue raised
    > > by both David Rubin and Martin Ambuhl, and it still uses
    > > an identifier reserved for the implementation,

    >
    > What reserved identifier? Do you mean the underscore before x?


    _x is reserved, yes. Unless you fully understand the rules as to which
    identifiers are reserved in what scope you should avoid starting any
    identifier with an underscore.

    > > and it still
    > > risks trouble with trap representations or if the system
    > > uses signed magnitude or ones' complement arithmetic ...

    >
    > He just wanted to extract the bytes of a long. Sometimes you do not
    > care how the
    > bytes are represented are in that long, just getting them is enough.
    >
    > You should not assign new values to byt, that could cause trap
    > representations as you said, but reading is allowed and safe.


    No it isn't. You have been told in another post that it is not.

    <snip>

    > [Freeware, Games and Humor]


    If the freeware is written by you in C then it is probably worth far
    less than it costs.
    --
    Mark Gordon
    Paid to be a Geek & a Senior Software Developer
    Although my email address says spamtrap, it is real and I read it.
     
    Mark Gordon, Oct 16, 2003
    #18
  19. Curt Geske

    Joe Wright Guest

    cody wrote:
    >
    > > > #include <stdio.h>
    > > > union _x
    > > > {
    > > > long lng;
    > > > char byt[sizeof long];
    > > > }
    > > >
    > > > better?

    > >
    > > Marginally. It still doesn't address the issue raised
    > > by both David Rubin and Martin Ambuhl, and it still uses
    > > an identifier reserved for the implementation,

    >
    > What reserved identifier? Do you mean the underscore before x?
    >
    > > and it still
    > > risks trouble with trap representations or if the system
    > > uses signed magnitude or ones' complement arithmetic ...

    >
    > He just wanted to extract the bytes of a long. Sometimes you do not care how
    > the
    > bytes are represented are in that long, just getting them is enough.
    >
    > You should not assign new values to byt, that could cause trap
    > representations as you said, but reading is allowed and safe.
    >
    > > ... but other than that, Mrs. Lincoln, how did you
    > > like the play?

    >
    > What do you mean with that?
    >


    Cody,

    They might be picking on you now. I'll move tentatively to your side.

    This snippet fixes your remaining syntax error (you'll see it easily)
    but provides fodder for our detractors.

    I contend, as you seem to, that accessing u.lng as components of u.byt[]
    is what unions are all about. We could be wrong.

    Accessing memory through (unsigned char *) seems to be guaranteed to
    work. I demonstrate both methods below. I don't understand why the first
    is wrong while the second is right. Duck! :)

    #include <stdio.h>

    typedef unsigned long ulong;
    typedef unsigned char uchar;

    union {
    ulong lng;
    uchar byt[ sizeof (ulong) ];
    } u;

    int main(void) {
    int i, j = sizeof (ulong);
    uchar *ucr = (uchar *)&u.lng;
    u.lng = 0x12345678;
    for (i = 0; i < j; ++i)
    printf(" 0x%02X", u.byt);
    puts("");
    for (i = 0; i < j; ++i)
    printf(" 0x%02X", ucr);
    return 0;
    }

    --
    Joe Wright http://www.jw-wright.com
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Oct 16, 2003
    #19
  20. Joe Wright <> wrote:

    >cody wrote:
    >>
    >> > > #include <stdio.h>
    >> > > union _x
    >> > > {
    >> > > long lng;
    >> > > char byt[sizeof long];
    >> > > }
    >> > >
    >> > > better?

    <snip>
    >I contend, as you seem to, that accessing u.lng as components of u.byt[]
    >is what unions are all about. We could be wrong.


    As I understand it, the main purpose of unions is to make it possible
    to define objects of a "generic" type that can hold values of different
    types, one at a time. It was not introduced to the language to have
    a convenient way of interpreting the same data (the implementations
    internal representation of a value) in different ways by writing to one
    union member and reading from another.

    Moral: you write a long, you read a long. ;-)

    Regards
    --
    Irrwahn
    ()
     
    Irrwahn Grausewitz, Oct 16, 2003
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. George Marsaglia

    Assigning unsigned long to unsigned long long

    George Marsaglia, Jul 8, 2003, in forum: C Programming
    Replies:
    1
    Views:
    728
    Eric Sosman
    Jul 8, 2003
  2. RB

    How to extract bytes from long?

    RB, Oct 15, 2003, in forum: C Programming
    Replies:
    46
    Views:
    1,385
  3. Daniel Rudy

    unsigned long long int to long double

    Daniel Rudy, Sep 19, 2005, in forum: C Programming
    Replies:
    5
    Views:
    1,235
    Peter Shaggy Haywood
    Sep 20, 2005
  4. Yandos
    Replies:
    12
    Views:
    5,148
    Pete Becker
    Sep 15, 2005
  5. Replies:
    5
    Views:
    303
    dprody
    Nov 5, 2007
Loading...

Share This Page