¿Qué significa un campo de bits de longitud cero sin nombre en C? [duplicate]

6 minutos de lectura

avatar de usuario de msc
msc

Vi el siguiente ejemplo en el borrador estándar de C (n1570):

$3.14 párrafo 4: Una estructura declarada como:

struct 
{
        char a;
        int b:5, c:11, :0, d:8;
        struct 
        { 
            int ee:8; 
        } e;
}

Asi que, Que hace :0 ¿significar?

yo se que campo de bits Es pero :0 es sin nombre, que no entiendo.

Cual es el proposito de :0 sin ningún identificador?

  • Nota al margen: si la colocación de bits dentro del campo de bits es importante, probablemente no debería usar campos de bits en primer lugar.

    – usuario694733

    28 de agosto de 2017 a las 10:47

  • No estoy muy seguro… ¿es apropiado el engaño marcado? No destaca este uso particular, en las respuestas.

    – Sourav Ghosh

    28 de agosto de 2017 a las 10:54

  • Me he tomado la libertad de reabrir ya que el duplicado marcado es potencialmente engañoso. Si alguien tiene alguna otra víctima, por favor haga el honor.

    – Sourav Ghosh

    28 de agosto de 2017 a las 11:28

  • @haccks señor, yo mismo reabrí esta pregunta, ya que anteriormente se marcó como engañada para la misma pregunta. ¿No estás de acuerdo con mi punto de vista?

    – Sourav Ghosh

    28 de agosto de 2017 a las 15:25

  • @haccks OK, eso es correcto, pero creo que esta pregunta tenía un aspecto diferente, con la cita específica. En mi opinión, no son engaños, sino que se complementan entre sí, sin ofender, señor.

    – Sourav Ghosh

    28 de agosto de 2017 a las 15:30


Avatar de usuario de Sami Kuhmonen
Sami Kuhmonen

Como el documento que vinculó explica justo antes:

Un campo de bits y un miembro adyacente que no es un campo de bits están en ubicaciones de memoria separadas. Lo mismo se aplica a dos campos de bits, si uno se declara dentro de una declaración de estructura anidada y el otro no, o si los dos están separados por una declaración de campo de bits de longitud ceroo si están separados por una declaración de miembro sin campo de bits

Es una forma de decirle al compilador que b y c puede/estará en la misma ubicación de memoria mientras que d debe estar separado de ellos y puede modificarse simultáneamente para b/c

  • Dado que los campos de bits dependen de la implementación, diría que no tiene sentido. Si necesita un diseño de bits específico, en mi opinión, es mucho mejor enmascarar los bits usted mismo.

    –Andrew Henle

    28 de agosto de 2017 a las 10:46

  • @AndrewHenle: sin sentido real, excepto para el acceso multiproceso

    – Alex C.

    28 de agosto de 2017 a las 12:50

Avatar de usuario de Sourav Ghosh
Sourav Ghosh

En primer lugar, veamos el capítulo §6.7.2.1, Especificadores de estructura y unión, P11. Dice,

Una implementación puede asignar cualquier unidad de almacenamiento direccionable lo suficientemente grande como para contener un campo de bits.
Si queda suficiente espacio, un campo de bits que sigue inmediatamente a otro campo de bits en una estructura se empaquetará en bits adyacentes de la misma unidad. […]

Pero, en caso de que queramos explícitamente dos miembros de campo de bits consecutivos, que “podrían estar” empaquetados en una sola ubicación de memoria para residir en una ubicación de memoria separada (es decir, unidad de almacenamiento direccionable), lo anterior es la forma de fuerza eso.

El siguiente párrafo, P12, menciona,

Una declaración de campo de bits sin declarador, pero solo dos puntos y un ancho, indica un
campo de bits sin nombre.126) Como caso especial, un miembro de estructura de campo de bits con un ancho de 0 indica que no se empaquetará ningún campo de bits adicional en la unidad en la que se colocó el campo de bits anterior, si lo hubiera.

siguiendo su ejemplo, esto asegura que los dos miembros del campo de bits que rodean el :0 residirán en una ubicación de memoria separada (no dentro de una sola unidad de almacenamiento direccionable, incluso si queda suficiente memoria para empaquetarlos en una sola). Esto tiene el efecto similar de tener un miembro sin campo de bits entre dos campos de bits, para forzar la separación de la ubicación de la memoria.

citando C11capítulo §3.14, NOTE 2 (énfasis mío)

Un campo de bits y un miembro adyacente que no es un campo de bits están en ubicaciones de memoria separadas. Lo mismo se aplica a dos campos de bits.si uno se declara dentro de una declaración de estructura anidada y el otro no, o si los dos están separados por una declaración de campo de bits de longitud cero, o si están separados por una declaración de miembro que no es un campo de bits.

Además, con respecto al uso (parte “por qué es necesario”)

[…] Los campos de bits b y c no puede modificarse al mismo tiempo, pero b y apor ejemplo, puede ser.


Apéndice:

En cuanto a la parte de concurrencia, de la NOTA 1

Dos subprocesos de ejecución pueden actualizar y acceder a ubicaciones de memoria separadas sin interferir entre sí.

y, del capítulo §5.1.2.4/P1,

Bajo una implementación alojada, un programa puede tener más de un subproceso de ejecución (o subproceso) ejecutándose simultáneamente. […]

Entonces, esta es una opción teóricamente viable, según el estándar.

  • Los campos de bits b y c no puede modificarse al mismo tiempo, pero b y apor ejemplo, puede ser. De donde viene eso? El lenguaje C en sí mismo no tiene el concepto de “concurrencia”, y los campos de bits dependen en gran medida de la implementación.

    –Andrew Henle

    28 de agosto de 2017 a las 10:50


  • @AndrewHenle Esa es una cita estándar. Pensé que era lo suficientemente claro como para marcar los capítulos. 🙂

    – Sourav Ghosh

    28 de agosto de 2017 a las 10:51

  • Hice una búsqueda de la copia estándar de C en open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf y no devolvió el resultado. Extraño. Interesante comentario sobre enhebrar en el estándar allí.

    –Andrew Henle

    28 de agosto de 2017 a las 10:55


  • @AndrewHenle Lo veo allí (incluso a través de su enlace)… Capítulo §3.14, NOTA 4. ¿Le importa volver a verificar?

    – Sourav Ghosh

    28 de agosto de 2017 a las 10:56


  • Lo encontré. ¿Quizás el texto en negrita en el PDF está interfiriendo con la búsqueda en el visor de PDF de Firefox? Cargando el estándar en Acrobat Reader, y la búsqueda de texto encuentra la cita sin ningún problema.

    –Andrew Henle

    28 de agosto de 2017 a las 10:59

avatar de usuario de paxdiablo
paxdiablo

Es una forma de garantizar que los archivos de bits, que de otro modo podrían combinarse en un único ubicación de la memoria, no lo son.

Por ejemplo, supongamos que tiene un carácter de 8 bits pero desea asegurarse de que sus dos campos de 3 bits estén en ubicaciones separadas (y, por lo tanto, se puedan modificar al mismo tiempo). Para lograr eso, podrías usar:

struct xyzzy {
    int first  : 3,
               : 0,
    int second : 3;
};

y no tendría que preocuparse por llenar el espacio manualmente, como con junk : 5.

Para los abogados de idiomas, C11 3.14 memory location /3 dice (mi énfasis):

Un campo de bits y un miembro adyacente que no es un campo de bits están en ubicaciones de memoria separadas. Lo mismo se aplica a dos campos de bits, si uno se declara dentro de una declaración de estructura anidada y el otro no, o si los dos están separados por una declaración de campo de bits de longitud cero, o si están separados por una declaración de miembro que no es un campo de bits.

¿Ha sido útil esta solución?