2012-06-19 14 views
5

La mia domanda riguarda l'indicazione di blocchi di memoria di dimensioni dispari.Puntatore C++ di dimensione bit specifica

Diciamo che ho un struct dichiarata in questo modo:

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

Supponiamo dichiarando campi di bit specifici nella struct è desiderabile (per questo che avremmo usato i campi di bit non è la domanda).

Se avessi voluto dichiarare un puntatore che punta a uno di quei campi, potrei provare qualcosa di simile:

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

Solo che questo produce l'errore "prendere l'indirizzo di un campo di bit non è permesso ".

Supponendo che vorremmo, c'è un modo per indicare questi campi in questo modo? So che C++ probabilmente riempirà i campi con il byte successivo (che in questo caso sarebbe 32 bit).

+3

Poiché i puntatori "puntano" ai byte, mi aspetto che questo comportamento sia normale, poiché non c'è modo di memorizzare l'indirizzo di qualcosa che potrebbe non essere un byte "completo". – ereOn

+1

Non credo che vedrete alcun padding per i membri bitfield che hanno specificato la loro dimensione di bit (o almeno, non potete essere sicuri di averne uno - è definito dall'implementazione). – RichieHindle

+0

@RichieHindle: in effetti, e per la maggior parte dei piccoli valori, non ci sarà il riempimento, poiché questo è esattamente il motivo per cui sono stati inventati i bitfield. – PlasmaHH

risposta

11

In C++, il valore più piccolo indirizzabile deve avere una dimensione di almeno 1 byte. Quindi No, non puoi prendere l'indirizzo di un campo di bit con i puntatori.

C++ 03 standard 9.6 bit-field:
Para 3:

... L'operatore di indirizzo & non si applicano per un po 'di campo, quindi non c'è non sono puntatori ai campi di bit. ....

6

Solo che questo produce l'errore "prendere l'indirizzo di un campo di bit non è permesso".

Questo è esplicitamente invalidato dalla norma. Vedi [class.bit] 9.6/3:

L'operatore di indirizzo & non si applicano per un po 'di campo, quindi non ci sono puntatori ai campi di bit.

Un byte (che è largo CHAR_BIT bit, dove CHAR_BIT è almeno 8) è il minimo possibile affrontare.

Supponendo che vorremmo, c'è un modo per puntare a quei campi in questo modo?

No. È possibile avere un puntatore a un oggetto del tipo che include struct. Questo è un riporto diretto da C; Vedi C FAQ 2.26:

bit-field sono scomodo quando si vuole anche essere in grado di manipolare qualche raccolta di bit nel suo insieme (magari per copiare un set di bandiere).

Si consiglia di guardare altre alternative come std::bitset o boost::dynamic_bitset.

0

Non c'è modo di ottenere un puntatore su un campo di bit. Se sei disposto a implementare una struttura equivalente da te stesso con lo , tuttavia, utilizzando i turni e le maschere , dovresti essere in grado di definire un puntatore intelligente. Qualcosa di simile :

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); 
    } 
}; 

(Questa è solo una vaga idea Probabilmente si vorrà sia un puntatore e un puntatore a const, e la durata della delega contro quella del suo proprietario può essere un. problema.)

Problemi correlati