2010-07-23 9 views
21

sizeof() no funciona cuando se aplica a campos de bits:¿Hay un bit equivalente a sizeof() en C?

# cat p.c 
    #include<stdio.h> 
    int main(int argc, char **argv) 
    { 
    struct { unsigned int bitfield : 3; } s; 
    fprintf(stdout, "size=%d\n", sizeof(s.bitfield)); 
    } 
# gcc p.c -o p 
    p.c: In function ‘main’: 
    p.c:5: error: ‘sizeof’ applied to a bit-field 

... obviamente, ya que no puede devolver un tamaño de punto flotante parcial o algo así. Sin embargo, trajo una pregunta interesante. ¿Hay allí un equivalente, en C, que le dirá el número de bits en una variable/tipo? Idealmente, también funcionaría para tipos regulares, como char y int, además de bitfields.

Actualización:

Si no hay un lenguaje equivalente de sizeof() para los campos de bits, lo que es la forma más eficiente de calcularlo - en tiempo de ejecución! Imagina que tienes bucles que dependen de esto, y no quieres que se rompan si cambias el tamaño del campo de bits, y no haces trampas justas y haces que el tamaño del campo de bits y la longitud del bucle sean macro. ;-)

Respuesta

16

No se puede determinar el tamaño de los campos de bits en C. Puede, sin embargo, averiguar el tamaño en bits de otros tipos usando el valor de CHAR_BIT, que se encuentra en limits.h. El tamaño en bits es simplemente CHAR_BIT * sizeof (tipo).

No suponga que un byte C es un octeto, es al menos 8 bit. Hay máquinas reales con 16 o incluso 32 bits de bytes.

En cuanto a tu edición: yo diría que un campo de bits int a: n; tiene un tamaño de n bits de por definición. Los bits adicionales de relleno cuando se colocan en una estructura pertenecen a la estructura y no al campo de bits.

Mi consejo: No use campos de bits, pero use (matrices de) unsigned char y trabaje con máscaras de bits. De esta forma, un buen comportamiento (desbordamiento, sin relleno) está bien definido.

+0

+1 genial, no sabía de CHAR_BIT. ¿y si necesitabas calcular el tamaño del campo de bit en tiempo de ejecución? – eruciform

+0

Eso simplemente no es posible (una de las razones por las cuales las personas evitan los campos de bits). Un compilador podría implementar esto como una extensión para esto, pero nunca he oído hablar de uno. – schot

+0

@schot: byte! = Char. En C, char es siempre de 8 bits, por lo que 'CHAR_BIT' siempre es 8. Independientemente de CPU/etc. Hace mucho tiempo podría haber sido diferente (la constante existe por razones históricas) pero ya no. Verifique C99, 'limits.h'. – Dummy00001

2

Es imposible encontrar un tamaño de campo de bits con sizeof(). Se refieren a C99:

  • 6.5.3.4 The sizeof operator, campo de bits claramente no es compatible con sizeof()
  • 6.7.2.1 Structure and union specifiers aquí se aclara que campo de bits no es auto miembro permanente.

De lo contrario, puede intentar asignar al miembro del campo de bits -1u (valor con todos los bits establecidos) y luego buscar el índice del bit más significativo. P.ej. (no probado):

s.bitfield = -1u; 
num_bits = ffs(s.bitfield+1)-1; 

man ffs para obtener más información.

+0

+1 esto está mirando más de cerca a un buscador de longitud óptimo. ¿Qué es 'ffs()'? – eruciform

+1

@eruciform: ffs = encuentra el primer conjunto. una función (a menudo asignada directamente a una instrucción de CPU) para encontrar el primer bit establecido en el int. los bits se numeran a partir de 1. si la entrada int es 0, entonces el retorno es demasiado 0. – Dummy00001

+0

¡agradable! esa es definitivamente una función que nunca he visto. ¡y aquí pensé que había visitado en gran medida los rincones con incrustaciones de telarañas de C a lo largo de los años! – eruciform