Thread: little endian machines

  1. #1
    Registered User
    Join Date
    Jun 2012
    Posts
    1

    little endian machines

    Code:
    #include <stdio.h>
     
    int main()
    {
            union s
           {
                int i;
                char ch[2];
           };
     
     
    union s obj;
    obj.i=255;
    printf("%d %d %d\n",obj.i,obj.ch[0],obj.ch[1]);
    
    
    }
    o/p :
    255 -1 0

    But what i expected was 255 255 0
    But How that -1 ?
    Explain please ?

    Thanks
    yogeesh serlathan
    forum4hackers.blogspot.com

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You might want to specify ch as an array of unsigned char. char can be signed or unsigned, depending on the implementation.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jun 2012
    Posts
    1
    My first post here so Hi everybody.

    00000000 00000000 00000000 11111111 is binary of your 255, int is 32 bits long on gcc.
    With little endian this data is stored in memory in reverse byte order so you have:
    11111111 00000000 00000000 00000000
    Binary representation of -1 is 1111 1111 when variable is signed. 1111 1110 is -2 and so on.
    You can even access 2nd and 3rd element of this array:
    Code:
    union u {
            int iNum;
            char aChar[2];
        }uVar={.iNum=255};
        printf("%d, %d, %d %d %d\n", uVar.iNum, uVar.aChar[0], uVar.aChar[1], uVar.aChar[2], uVar.aChar[3]);
    ps sorry for my poor english

  4. #4
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Don't use unions like that. It'll usually work, but technically the C++ standard only permits reading the union element that was last written to. In other words, you can't write iNum and then read aChar, unless you're cool with implementation-specific behavior.


    P.S. In C++, it's not <stdio.h> but <cstdio>. All the old headers from the C standard libary can be gotten at by dropping the ".h" and prepending a "c".

    <assert.h> -> <cassert>
    <stdlib.h> -> <cstdlib>
    <stddef.h> -> <cstddef>

    etc.

    That also means that all the functions, types, etc. that used to be in the old headers are now in namespace std, so technically you should be writing std::printf() instead of just printf().
    Last edited by antred; 06-07-2012 at 05:29 AM.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by antred View Post
    That also means that all the functions, types, etc. that used to be in the old headers are now in namespace std, so technically you should be writing std:rintf() instead of just printf().
    Or... you know, just use std::cout.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by antred View Post
    Don't use unions like that. It'll usually work, but technically the C++ standard only permits reading the union element that was last written to. In other words, you can't write iNum and then read aChar, unless you're cool with implementation-specific behavior.
    Well, yeah - but it is also a moot point.

    Every available approach for reinterpreting types (eg interpreting the memory representing an X as if it was a Y) yields some form of implementation defined or undefined behaviour.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Quote Originally Posted by grumpy View Post
    Every available approach for reinterpreting types (eg interpreting the memory representing an X as if it was a Y) yields some form of implementation defined or undefined behaviour.
    Well, that's true I guess but then I don't see any need for that kind of stuff if all you want to do is endianness-related conversions. Oh and correct me if I'm wrong, but shouldn't the following be free of any "undefinedness"?

    Code:
    #include <iostream>
    
    bool isLittleEndian()
    {
        const unsigned char byteArray[ sizeof( unsigned short int ) ] = { 1 };
        const unsigned short int* const asUShort = reinterpret_cast < const unsigned short int* > ( byteArray );
    
        return *asUShort == static_cast < unsigned short int > ( byteArray[ 0 ] );
    }
    
    int main()
    {
        if ( isLittleEndian() )
        {
            std::cout << "little-endian\n";
        }
        else
        {
            std::cout << "big-endian\n";
        }
    }
    I don't think there is anything implementation-specific in the memory representation of unsigned, built-in integral types, or is there?

    P.S. Except of course sizeof( unsigned int ), etc. ...
    Last edited by antred; 06-07-2012 at 06:36 AM.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Nope. The code exhibits undefined behaviour when dereferencing asUShort.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  9. #9
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Quote Originally Posted by grumpy View Post
    Nope. The code exhibits undefined behaviour when dereferencing asUShort.
    Seriously? Can you explain why (or point me to the relevant section in the C++ standard)?

  10. #10
    Registered User antred's Avatar
    Join Date
    Apr 2012
    Location
    Germany
    Posts
    257
    Ah well, found it. It seems you're right.


    5.2.10 Reinterpret cast
    3) The mapping performed by reinterpret_cast is implementation-defined. [Note: it might, or might
    not, produce a representation different from the original value. ]
    And no mention of any exceptions to this rule.

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You could write the array to file and then read it into the other array

    Okay okay, I'm just getting silly there.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by antred View Post
    And no mention of any exceptions to this rule.
    What you found about reinterpret_cast<> is only part of it.

    The reinterpret_cast<> has implementation defined behaviour, as you have found.

    Regardless of how the reinterpret_cast<> does any mapping, the dereferencing of asUShort (i.e. the "*asUShort") ALSO has undefined behaviour, since it treats memory containing a value of type X as if it was a value of type Y.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  13. #13
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    has undefined behaviour
    I'm not on a machine that has the standard available so I'm compelled (by curiosity) to ask: isn't that still implemented defined instead of undefined?

    Soma

  14. #14
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Type conversions between values (even pointer values) give implementation-defined results.

    Dereferencing a pointer has undefined behaviour, if the pointer is of a different type from what is actually stored at that address.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  15. #15
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Type conversions between values (even pointer values) give implementation-defined results.
    With the exception that normal pointers must "round trip" through `void *' of course.

    Dereferencing a pointer has undefined behaviour, if the pointer is of a different type from what is actually stored at that address.
    Yes. I understood what you were saying. I wasn't arguing with you about it. I was hoping you could give the context from the standard for it.

    I wasn't looking for a quote of anything. I was just looking for the context of that portion of the standard. I can look it up myself later.

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Little endian and Bit endian advantages and disadvantages
    By nkrao123@gmail. in forum C Programming
    Replies: 4
    Last Post: 09-11-2011, 04:40 AM
  2. Any significant Big Endian Machines?
    By abachler in forum Tech Board
    Replies: 9
    Last Post: 01-29-2009, 01:53 PM
  3. big endian-small endian problem
    By kapil1089thekin in forum C Programming
    Replies: 3
    Last Post: 05-15-2008, 06:47 PM
  4. Big Endian Little Endian Complex- Converting Characters
    By bd02eagle in forum C Programming
    Replies: 3
    Last Post: 07-11-2006, 01:01 AM
  5. Big endian/Little endian conversion
    By bonkey in forum Windows Programming
    Replies: 5
    Last Post: 09-25-2002, 02:29 PM

Tags for this Thread