2012-06-19 5 views
5

Meine Frage bezieht sich auf Blöcke von Speicher einer ungeraden Größe.C++ Zeiger der spezifischen Bitgröße

Lassen Sie uns sagen, ich habe eine struct wie so erklärt:

typedef struct{ 
    int32 val1 : 29; 
    int32 val2 : 26; 
    char val3; 
}MyStruct; 

Lassen Sie uns bestimmte Bitfelder deklarieren übernehmen in der Struktur wünschens ist (warum wir die Bitfelder verwenden würde, ist nicht die Frage).

Wenn ich einen Zeiger erklären wollte, die zu einem dieser Felder zeigt, könnte ich so etwas wie dies versuchen:

MyStruct test; 
int32 *myPtr = &(test.val1); 

Abgesehen davon, dass dies erzeugt den Fehler "die Adresse eines Bitfeldes nehmen nicht ist erlaubt ".

Vorausgesetzt, dass wir wollen, gibt es eine Möglichkeit, auf diese Felder auf diese Weise zu zeigen? Ich weiß, dass C++ die Felder wahrscheinlich auf das nächste Byte auffüllen wird (was in diesem Fall 32 Bit wäre).

+3

Da Zeiger auf Bytes "zeigen", würde ich erwarten, dass dieses Verhalten normal ist, da es keine Möglichkeit gibt, die Adresse von etwas zu speichern, das möglicherweise kein "vollständiges" Byte ist. – ereOn

+1

Ich glaube nicht, dass Sie für Bitfeld-Mitglieder, die ihre Bit-Größe angegeben haben, Padding sehen (oder Sie können zumindest nicht sicher sein, welche Bit-Größe es hat - es ist implementation-defined). – RichieHindle

+0

@RichieHindle: In der Tat, und für die meisten kleinen Werte wird es keine Auffüllung geben, da dies genau der Grund ist, warum Bitfelder erfunden wurden. – PlasmaHH

Antwort

11

In C++ muss der kleinste adressierbare Wert eine Größe von mindestens 1 Byte haben. Also Nein, Sie können die Adresse eines Bitfeldes nicht mit Zeigern aufnehmen.

C++ 03 Standard-9,6-Bit-Felder:
Para 3:

... Der Adressoperator & darf nicht auf ein Bit-Feld angelegt werden, so dass es sind keine Zeiger auf Bitfelder. ....

6

Abgesehen davon, dass dies die Fehler produziert „um die Adresse eines Bitfeldes nehmen ist nicht erlaubt“.

Dies wird vom Standard explizit nicht zugelassen. Siehe [class.bit] 9.6/3:

Der Adressoperator & darf nicht auf ein Bit-Feld angelegt werden, so dass es keine Hinweise auf bitfields.

Ein Byte (die CHAR_BIT Bits breit ist, wobei CHAR_BIT mindestens 8) ist die minimal Sie adressieren können.

Vorausgesetzt, dass wir wollen, gibt es eine Möglichkeit, auf diese Felder auf diese Weise zu zeigen?

Nein. Sie können jedoch einen Zeiger auf ein Objekt des umschließenden Typs struct haben. Dies ist eine direkte Übertragung von C; Siehe C FAQ 2.26:

Bit-Felder unbequem sind, wenn Sie auch in der Lage sein wollen einige Sammlung von Bits als Ganzes zu manipulieren (vielleicht eine Reihe von Flaggen zu kopieren).

Sie können auch andere Alternativen wie std::bitset oder boost::dynamic_bitset betrachten.

0

Es gibt keine Möglichkeit, einen Zeiger auf ein Bitfeld zu bekommen. Wenn Sie bereit sind, eine äquivalente Struktur selbst zu implementieren, verwenden Sie Shifts und Masken, sollten Sie in der Lage sein, einen intelligenten Zeiger in es zu definieren. Etwas wie:

class BitFieldPointer 
{ 
    unsigned* myData; 
    unsigned myMask; 
    unsigned myShift; 

    class DereferenceProxy 
    { 
     BitFieldPointer const* myOwner; 
    public: 
     DereferenceProxy(BitFieldPointer const* owner) : myOwner(owner) {} operator unsigned() const 
     { 
      return (*myOwner->myData && myOwner->myMask) >> myOwner->myShift; 
     } 

     void operator=(unsigned new_value) const 
     { 
      *myData = (*myOwner->myData && ~myOwner->myMask) | 
        ((new_value << myOwner->myShift) && myOwner->myMask); 
     } 
    }; 
public: 
    // ... 
    DereferenceProxy operator*() const 
    { 
     return DereferenceProxy(this); 
    } 
}; 

(Dies ist nur eine grobe Vorstellung Sie werden wahrscheinlich beide wollen einen Zeiger und einen Zeiger auf const, und die Lebensdauer des Proxy gegen die seinen Besitzer kann eine sein. Ausgabe.)