utiliza sintaxis reservar programacion memoria manejo dinamica como avanzada c++ c bit-fields

c++ - sintaxis - Uso práctico de campos de bits de longitud cero



sintaxis de malloc en c (4)

No estoy totalmente seguro de C, pero C ++ permite campos de bits sin nombre de 0 de longitud. Por ejemplo:

struct X { int : 0; };

  • Primera pregunta: ¿En qué usos prácticos se puede pensar?
  • Pregunta dos: ¿Qué usos prácticos del mundo real (si hay alguno) conoces?

Editado el ejemplo después de la respuesta del crimen de hielo

Editar: OK, gracias a las respuestas actuales ahora sé el propósito teórico. Pero las preguntas son sobre usos prácticos, así que todavía tienen :)


El estándar (9.6 / 2) solo permite 0 campos de bits de longitud como caso especial :

Como caso especial, un campo de bit sin nombre con un ancho de cero especifica la alineación del siguiente campo de bit en un límite de unidad de asignación. Solo cuando se declara un campo de bits sin nombre, la expresión constante puede ser un valor igual a cero .

El único uso se describe en esta cita, aunque nunca lo he encontrado en el código práctico.

Para el registro, acabo de probar el siguiente código en VS 2010:

struct X { int i : 3, j : 5; }; struct Y { int i : 3, : 0, j : 5; // nice syntax huh ? }; int main() { std::cout << sizeof(X) << " - " << sizeof(Y) << std::endl; }

La salida en mi máquina es de hecho: 4 - 8 .


Esto es de MSDN y no está marcado como específico de Microsoft, así que supongo que esto es un estándar común de C ++:

Un campo de bit sin nombre de ancho 0 fuerza la alineación del siguiente campo de bit al siguiente límite de tipo, donde tipo es el tipo del miembro.


Utiliza un campo de bits de longitud cero para que el compilador diseñe una estructura que coincida con algún requisito externo, ya sea la noción del diseño de otro compilador o arquitectura (estructuras de datos multiplataforma, como en un formato de archivo binario). ) o los requisitos de un estándar de nivel de bit (paquetes de red u códigos de operación de instrucción).

Un ejemplo del mundo real es cuando NeXT transfirió el kernel xnu de la arquitectura Motorola 68000 (m68k) a la arquitectura i386. NeXT tenía una versión en funcionamiento de m68k de su kernel. Cuando lo trasladaron a i386, descubrieron que los requisitos de alineación del i386 diferían de los m68k de tal forma que una máquina m68k y una máquina i386 no coincidían en el diseño de la estructura BOOTP específica del proveedor NeXT. Para hacer que el diseño de la estructura i386 concuerde con el m68k, agregaron un campo de bits sin nombre de longitud cero para forzar a la unión estructura NV1 / NV1 nv_U a 16 bits.

Aquí están las partes relevantes del código fuente de Mac OS X 10.6.5 xnu:

/* from xnu/bsd/netinet/bootp.h */ /* * Bootstrap Protocol (BOOTP). RFC 951. */ /* * HISTORY * * 14 May 1992 ? at NeXT * Added correct padding to struct nextvend. This is * needed for the i386 due to alignment differences wrt * the m68k. Also adjusted the size of the array fields * because the NeXT vendor area was overflowing the bootp * packet. */ /* . . . */ struct nextvend { u_char nv_magic[4]; /* Magic number for vendor specificity */ u_char nv_version; /* NeXT protocol version */ /* * Round the beginning * of the union to a 16 * bit boundary due to * struct/union alignment * on the m68k. */ unsigned short :0; union { u_char NV0[58]; struct { u_char NV1_opcode; /* opcode - Version 1 */ u_char NV1_xid; /* transcation id */ u_char NV1_text[NVMAXTEXT]; /* text */ u_char NV1_null; /* null terminator */ } NV1; } nv_U; };


struct X { int : 0; };

es un comportamiento indefinido en C.

Ver (énfasis mío):

(C99, 6.7.2.1p2) "La presencia de una struct-declaration-list en un struct-o-union-specifier declara un nuevo tipo, dentro de una unidad de traducción. La struct-declaration-list es una secuencia de declaraciones para el miembros de la estructura o unión. Si struct-declaration-list no contiene miembros con nombre, el comportamiento no está definido ".

(C11 tiene la misma redacción)

Puede usar un campo de bit sin nombre con ancho 0 pero no si no hay otro miembro nombrado en la estructura.

Por ejemplo:

struct W { int a:1; int :0; }; // OK struct X { int :0; }; // Undefined Behavior

Por cierto para la segunda declaración, gcc emite un diagnóstico (no requerido por el estándar C) con -pedantic .

Por otra parte:

struct X { int :0; };

se define en GNU C. Se utiliza, por ejemplo, en el kernel de Linux ( include/linux/bug.h ) para forzar un error de compilación utilizando la siguiente macro si la condición es verdadera:

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))