warning C4244: '=' : conversion from 'DWORD' to 'BYTE', possible loss of data



  • Ich habe folgenden code wobei func_bytes ein array aus unsigned chars also BYTES ist und CALL_BYTES ein DWORD:

    func_bytes[9]  = (CALL_BYTES & 0x000000FF);
    
    func_bytes[10] = (CALL_BYTES & 0x0000FF00) >> 8;
    
    func_bytes[11] = (CALL_BYTES & 0x00FF0000) >> 16;
    
    func_bytes[12] = (CALL_BYTES & 0xFF000000) >> 24;
    

    Der code soll den DWORD in die einzelnen bytes zerlegen, funktioniert auch jedoch bekomme ich nur bei dieser Zeile :

    func_bytes[11] = (CALL_BYTES & 0x00FF0000) >> 16;
    

    eine Warnung. Auch wenn ich sie an den anfang verschiebe gibt mir VS13 immer nur bei der zeile die warnung aus dem titel..

    Woran könnte das liegen ?



  • Ein BYTE (bzw. unsigned char ) ist genau ein Byte groß, ein DWORD (bzw. unsigned int ) hingegen vier Bytes.

    Daher können nicht alle DWORD -Werte in einem BYTE dargestellt werden, d.h. bei der Zuweisung eines DWORD -Wertes an ein BYTE -Variable kann es im Allgemeinen zum Datenverlust kommen.

    Durch deine Bit-Operationen zerlegst Du zwar den DWORD -Wert in einzelne Bytes, technisch gesehen steht rechts der Zuweisung aber immer noch ein DWORD .

    Ich denke in diesem Fall ist die Zuweisung sicher, da Du zwar ein DWORD an ein BYTE zuweist, der DWORD -Wert aber immer zwischen 0x00000000 und 0x000000FF liegen wird. Nur weiß der Compiler das nicht 😉

    Du könntest den Code wie folgt ändern:

    func_bytes[11] = static_cast<BYTE>((CALL_BYTES & 0x00FF0000) >> 16);
    


  • Bitte lies meine frage nochmal.

    "Der code soll den DWORD in die einzelnen bytes zerlegen..."

    + Ich 'schneide' das DWORD doch auf einen Byte herunter durch das FF und das shiften.

    Edit: Habe gerade die bearbeitete Version gelesen :), aber warum weiß der Compiler es nur bei der einen Version mit 00FF0000 und >> 16 nicht?



  • Okay, das habe ich schon verstanden.

    Aber nach dem binären UND (** & ) sowie dem anschließenden Bit-Shift ( >> **) ist dein DWORD trotzdem noch immer ein DWORD - auch wenn sich hier leicht beweisen lässt, dass das Ergebnis immer zwischen 0x00000000 und 0x000000FF liegt 😉

    Der Compiler beschwert sich also schlichtweg über die Typen-Umwandlung (von DWORD zu BYTE ), ohne zu berücksichtigen welche Werte zur Laufzeit tatsächlich auftreten werden.

    (Auch wenn es in diesem Beispiel offensichtlich ist, dürfte es im allgemeinen Fall ziemlich schwierig, allein durch statische Analyse vorab zu bestimmen, welche Werte zur Laufzeit als Ergebnis auftreten können)



  • Ceno schrieb:

    Habe gerade die bearbeitete Version gelesen 🙂

    Alles klar 😃

    Ceno schrieb:

    aber warum weiß der Compiler es nur bei der einen Version mit 00FF0000 und >> 16 nicht?

    Gute Frage. Vllt gibt der Compiler die Warning nur 1× aus und das ist eben zufällig diese Zeile? 😕

    Wie dem auch sei, wenn Du das Ergebnis explizit auf BYTE castest, dann sollte die Warning sofort verschwinden. Da das Ergebnis ohnehin implizit auf BYTE gecastet wird, sollte der explizite Cast auf keinen Fall schaden...



  • Okay werde das probieren, wobei die Warnung ja wie oben beschrieben auch da erscheint wenn ich die Zeile vor die anderen packe. Ich glaube nicht das VS da zufällig eine auswählt!


Anmelden zum Antworten