char array in Bitfield struct?



  • Hiho,

    ich habe einen char array welchen ich in ein Bitfield struct casten möchte. Problem ist aber das wenn ich mehr als 8 Bit vom char array nehmen möchte, geht es einfach nicht.

    #pragma pack(1)
    struct SENSOR {
    	short x1 : 10;
    	short y1 : 10;
    	short x2 : 10;
    	short y2 : 10;
    }
    
    unsigned char data[] = { 0x0B, 0xCE, 0x90, 0xD0, 0xEE, 0x88 };
    // 0x0B      0xCE       0x90       0xD0       0xEE      0x88
    // 1011      11001110   10010000   11010000   11101110  10001000
    // [00001011 11][001110 1001][0000 110100][00 11101110] 10001000
    //     = 47         = 233        = 52          = 238
    
    auto sensor = reinterpret_cast<SENSOR*>(data);
    

    Leider enthält sensor nicht die richtigen Daten (die als Kommentar gezeigten Daten sind das was eigentlich raus kommen soll. Wenn ich testweise immer nur 8 bit lesen, kommt binär genau das ras was auch drin steht.

    Spoocy


  • Mod

    Das pack brauchste nicht. Der Standard garantiert dass x1 das erste Byte belegt und das alle Bitfields in der selben allocation unit residieren.
    Edit: Ahh, pack macht die besagte unit tatsächlich kleiner. Ändert aber ja nichts am Resultat.

    Allerdings machst du hier eine ungerechtfertigte Annahme: Die Bits der Member liegen alle hintereinander und in der Reihenfolge der Deklaration. Das ist jedoch wahrscheinlich nicht der Fall. Beachte die Notiz:

    §9.6/1 schrieb:

    [ Note: Bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. — end note ]


  • Mod

    Dieses Beispiel zeigt auf wie die Bitfields verteilt sind:

    struct [[gnu::packed]] SENSOR {
    	short x1 : 10;
    	short y1 : 10;
    	short x2 : 10;
    	short y2 : 10;
    };
    
    #include <iostream>
    #include <bitset>
    int main() {
    	SENSOR s{0b1111111111, 0, 0b1100110011, 0b0101010101};
    	for (auto c : reinterpret_cast<unsigned char(&)[sizeof s]>(s))
    		std::cout << std::bitset<8>(c) << ' ';
    }
    

    Du musst was eigenes Basteln um das gewünschte Verhalten zu bekommen.



  • Warum muss es per casten passieren? Ist das ein Performance Problem? Wenn ja bedenke, das du (wuerde das casten funktionieren) das Performance Problem dann beim Lesen aus der Struktur haettest.


Anmelden zum Antworten