Knifflige Frage zum bitweisen NICHT (~)



  • Hallo,

    ich habe eine kleine Verständnisfrage zum ~ -Operator:

    Kurze Erläuterung: Zur einfachen Fehlererkennung über ein unsicheres Medium schicke ich einen Datenwert zweimal hintereinander, einmal normal und einmal invertiert.

    Beim Empfänger werden beide Werte a und b empfangen und verglichen, ob ein Fehler vorliegt:

    unsigned int a = 8;
        unsigned int b = ~a;
    
        if ( a != ~b )
            printf( "Fehler");
    

    Führt man den Code aus, kommt wie zu erwarten KEIN Fehler heraus.

    Verwende ich allerdings einen anderen Datentyp:

    unsigned short a = 8;
        unsigned short b = ~a;
    
        if ( a != ~b )
            printf( "Fehler");
    
    unsigned char a = 8;
        unsigned char b = ~a;
    
        if ( a != ~b )
            printf( "Fehler");
    

    Hier wird interessanterweise bei beiden ein angeblicher Fehler erkannt! Bei unsigned long long kommt wieder kein Fehler.

    Jetzt meine zwei Fragen:

    * Warum ändert der ~ -Operator implizit den Datentyp bei 8 und 16-Bit-Typen?

    * Und wenn er das schon tun muß, warum erzeugt dann die Zeile

    unsigned char b = ~a;
    

    nicht schon einen Fehler? Stichwort int zu char Casting und dabei möglichem Datenverlußt?

    Danke,
    Chriss


  • Administrator

    cmdev schrieb:

    * Warum ändert der ~ -Operator implizit den Datentyp bei 8 und 16-Bit-Typen?

    Weil der Standard es so verlangt, dass hier automatisch eine Integer Promotions durchgeführt wird.

    cmdev schrieb:

    * Und wenn er das schon tun muß, warum erzeugt dann die Zeile

    unsigned char b = ~a;
    

    nicht schon einen Fehler? Stichwort int zu char Casting und dabei möglichem Datenverlußt?

    Weil das eine einfache Zuweisung ist, wodurch eine implizite Konvertierung vorgenommen wird. Auch das folgende geht ohne Probleme:

    unsigned char b = 1.2341;
    

    Man kann dies mit folgendem gleichsetzen:

    unsigned char b = (unsigned char)1.2341;
    

    Grüssli



  • Wobei

    unsigned char b = 1.2341;
    

    bei VC eine Warnung erzeugt:

    warning C4244: 'initializing' : conversion from 'double' to 'unsigned char', possible loss of data

    GCC sagt allerdings wirklich nichts. Somit hätte ich mich wenigstens über einen Hinweis von VC gefreut.

    Hab mich gerade über Integer Promotions schau gemacht. Klingt an sich logisch. Produziert aber sicher einige Fehler, bin mit Sicherheit nicht der erste mit dem Problem.

    Danke für die Info!


Anmelden zum Antworten