2012-06-19 25 views
5

Mi pregunta es sobre señalar trozos de memoria de un tamaño impar.Puntero C++ de tamaño de bit específico

Digamos que tengo un struct declarada como tal:

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

Asumamos declarar campos de bits específicos en la estructura es deseable (por lo que haría uso de los campos de bits no es la cuestión).

Si quería declarar un puntero que apunta a uno de esos campos, podría intentar algo como esto:

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

Excepto que esto produce el error "tomar la dirección de un campo de bits no es permitido ".

Suponiendo que quisiéramos, ¿hay alguna manera de señalar esos campos de esta manera? Sé que C++ probablemente rellenará los campos con el siguiente byte (que en este caso sería de 32 bits).

+3

Dado que los punteros "apuntan" a los bytes, esperaría que este comportamiento fuera normal, ya que no hay forma de almacenar la dirección de algo que puede no ser un byte "completo". – ereOn

+1

No creo que veas ningún relleno para los miembros del campo de bits que tengan el tamaño de bit especificado (o al menos, no puedes estar seguro de obtener ninguno; está definido por la implementación). – RichieHindle

+0

@RichieHindle: de hecho, y para la mayoría de los valores pequeños, no habrá relleno, ya que esta es exactamente la razón por la que se inventaron los campos de bits. – PlasmaHH

Respuesta

11

En C++, el valor direccionable más pequeño debe tener un tamaño de al menos 1 byte. Entonces, no, no puede tomar la dirección de un campo de bit con punteros.

C++ 03 estándar de 9,6 campos de bits:
para 3:

... El operador de dirección & no se aplicarán a un campo de bits, por lo que hay no hay punteros a los campos de bits. ....

6

Excepto que esto produce el error "tomar la dirección de un campo de bits no está permitido".

Esto está explícitamente prohibido por la norma. Ver [class.bit] 9.6/3:

El operador de dirección & no se aplicarán a un campo de bits, por lo que no hay punteros a campos de bits.

Un byte (que es CHAR_BIT bits de ancho, donde CHAR_BIT es, al menos, 8) es el mínimo que se puede tratar.

Suponiendo que quisiéramos, ¿hay alguna manera de señalar estos campos de esta forma?

No. Sin embargo, puede tener un puntero a un objeto del tipo struct adjunto. Este es un traslado directo desde C; Ver C FAQ 2.26:

campos de bits son inconvenientes cuando también quiere ser capaz de manipular alguna colección de bits en su conjunto (tal vez para copiar un conjunto de indicadores).

Es posible que desee buscar otras alternativas tales std::bitset o boost::dynamic_bitset.

0

No hay forma de obtener un puntero a un campo de bit. Si está dispuesto a implementar una estructura equivalente usted mismo, sin embargo, utilizando turnos y máscaras , debe poder definir un puntero inteligente en él. Algo como:

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

(Esto es sólo una idea aproximada Usted probablemente querrá tanto un puntero y un puntero a const , y la vida útil de la representación frente a la de su propietario puede ser un . problema.)

Cuestiones relacionadas