Endianess



  • Hallo,

    ich habe gerade folgenden Code gefunden zum Test, ob die Maschine Little oder Big Endian ist:

    #include <stdio.h>
    main () {
    int i = 0x12345678;
    if (*(char *)&i == 0x12)
    printf ("Big endian\n");
    else if (*(char *)&i == 0x78)
        		printf ("Little endian\n");
    }
    

    Das heisst also, C++ speichert das Bytemuster von Variablen immer im Format der Maschine ab und hat nicht ein eigenes?
    Was mir nicht klar ist: Wenn ich mit Bitoperatoren rumhantiere, z.B.:

    int foo = ..
    int bar = foo & (1 << 31)
    

    dann wuerde ich mit diesem Code auf einer Big Endian Maschine doch andere Ergebnisse kriegen als auf einer Little Endian Maschine? Muss ich dann alle Bitoperationen per #ifdef schuetzen? 😕



  • [quote="LittleBigPlanet"]
    Das heisst also, C++ speichert das Bytemuster von Variablen immer im Format der Maschine ab und hat nicht ein eigenes?[/cpp] richtig.

    Was mir nicht klar ist: Wenn ich mit Bitoperatoren rumhantiere,
    dann wuerde ich mit diesem Code auf einer Big Endian Maschine doch andere Ergebnisse kriegen als auf einer Little Endian Maschine?

    Nein. Wenn der bitshift über byte-Grenzen hinausgeht, gehts zum Byte mit der nächst kleineren Adresse. Beim BE ist das in der Notation links, beim LE in der Notation rechts.

    short s = 0xFF; //bzw. 0x00FF - BE: 00 FF - LE: FF 00
    s <<=2; //d.h. 0x03FC - BE: 03 FC - LE: FC 03
    

    Man kann es sich alternativ "physikalisch" auch so vorstellen, dass die bytes immer gleich im Speicher liegen, BE aber von links nach rechts adressiert und LE von rechts nach links:

    64 bit integer 0xFF vor und nach bitshift um 2:

    |0   .... BE ...     7|
    00 00 00 00 00 00 00 FF 
    00 00 00 00 00 00 03 FC
    |7    ... LE ...     0|
    


  • Dann koennte ich es mir vereinfacht auch so vorstellen:
    Wenn ich direkt byteweise den Speicher lese, ist die Endianess wichtig.

    Wenn ich auf der Variablen mit Bit-Operatoren arbeite, kann ich mir einfach vorstellen, dass so gerechnet wird wie man es aufm Blatt Papier machen wuerde (quasi Big Endian). Die Operation ist quasi virtualisiert.

    Passt das so?



  • Übrigens ist dein Code zu 100% C und kein bisschen C++.



  • EOutOfResources schrieb:

    Übrigens ist dein Code zu 100% C und kein bisschen C++.

    Hier geht es aber nicht um den geposteten Code, also ist das eigentlich irrelevant.



  • _matze schrieb:

    Hier geht es aber nicht um den geposteten Code, also ist das eigentlich irrelevant.

    Mir geht es darum, dass der Code auf einem ISO-Compiler für C++ nicht kompilieren darf!



  • EOutOfResources schrieb:

    _matze schrieb:

    Hier geht es aber nicht um den geposteten Code, also ist das eigentlich irrelevant.

    Mir geht es darum, dass der Code auf einem ISO-Compiler für C++ nicht kompilieren darf!

    Ja, ich habe auch gesehen, dass der Rückgabewert von main fehlt, aber mir geht es darum, das es nicht darum geht. 🤡



  • EOutOfResources schrieb:

    _matze schrieb:

    Hier geht es aber nicht um den geposteten Code, also ist das eigentlich irrelevant.

    Mir geht es darum, dass der Code auf einem ISO-Compiler für C++ nicht kompilieren darf!

    Mal abgesehen vom fehlenden int vor der main ist alles okay. Auch für C++.



  • Es ist einfach so: hier wird LE/BE diskutiert. Der Eingangscode ist hierzu irrelevant. Es ist also unnötig, zu beweisen, wie gut man zwischen bösem C und "wahrem" C++ unterscheiden kann. 😃



  • Was soll jetzt diese unnoetige Korinthenkackerei von EOutOfResources?

    Passt meine Sichtweise aus Posting 2?



  • EOutOfResources schrieb:

    _matze schrieb:

    Hier geht es aber nicht um den geposteten Code, also ist das eigentlich irrelevant.

    Mir geht es darum, dass der Code auf einem ISO-Compiler für C++ nicht kompilieren darf!

    Ist das so?



  • LittleBigPlanet schrieb:

    Was soll jetzt diese unnoetige Korinthenkackerei von EOutOfResources?

    Sowas kommt vor hier im Forum. Einfach ignorieren, schlimmstenfalls füttert man sonst schnell irgendwelche Trolle.

    Passt meine Sichtweise aus Posting 2?

    Grob, ja.



  • Michael E. schrieb:

    EOutOfResources schrieb:

    _matze schrieb:

    Hier geht es aber nicht um den geposteten Code, also ist das eigentlich irrelevant.

    Mir geht es darum, dass der Code auf einem ISO-Compiler für C++ nicht kompilieren darf!

    Ist das so?

    Na ja, das stimmt schon, denke ich, oder nicht? main muss int als Rückgabewert haben, und default-int gibt's nicht in C++. Ach, ist ja auch egal, und bringt LittleBigPlanet nicht weiter...



  • Dabei habe ich jetzt auch direkt eine Frage. Wenn die Shifoperatoren unabhängig von der Endianess arbeiten, tun das dann auch die restlichen Bitoperatoren oder sind die Endianessabhängig?



  • _matze schrieb:

    Michael E. schrieb:

    Ist das so?

    Na ja, das stimmt schon, denke ich, oder nicht? main muss int als Rückgabewert haben, und default-int gibt's nicht in C++. Ach, ist ja auch egal, und bringt LittleBigPlanet nicht weiter...

    Ich denke mal M.E. zielt drauf ab, dass der Standard Extensions für Compiler erlaubt, die anderweitig ungültigen Code gültig machen dürfen. Aber wie du sagts, hilft das dem Fragesteller nicht.

    Back to topic.



  • GroßerEnder schrieb:

    Wenn die Shifoperatoren unabhängig von der Endianess arbeiten, tun das dann auch die restlichen Bitoperatoren oder sind die Endianessabhängig?

    Bei & , | , ^ und ~ wird ja Bit für Bit unabhängig verknüpft, daher spielt die Endianess keine Rolle.



  • Das heißt dieser Code

    unsigned high = 42;
    unsigned char low = 23;
    unsigned short both = static_cast<unsigned short>(high << 8 | low);
    std::cout << both << std::endl;
    

    ist doch Plattformunabhängig?
    (Aus nem anderen Thread kopiert)



  • So gut wie. Das Einzige, was IMHO schief gehen kannst, ist, dass ein Short zu klein sein kann, um zwei Chars aufzunehmen. Aber dafür bräuchte man schon mal mindestens 9-Bit-Chars. Sprich: Es geht für normale Programmierer immer gut.


Anmelden zum Antworten