¿Cuál es el tamaño de una estructura vacía en C?

5 minutos de lectura

avatar de usuario
Vinit Dhatrak

Según yo, es cero, pero parece que hay un poco de confusión aquí.

Lo he probado con el compilador gcc y me da cero como salida. Sé que en C++, el tamaño de una clase vacía es 1. Avíseme si me falta algo aquí.

  • @Ben S ¡Gracias por reformatear la pregunta!

    – Vinit Dhatrak

    26 de octubre de 2009 a las 18:39

  • C++ Standard (al menos C++03) no establece ese resultado de sizeof aplicado a una clase/estructura vacía es igual a 1.

    – Kirill V. Lyadvinsky

    26 de octubre de 2009 a las 19:29

avatar de usuario
Johannes Schaub – litb

Una estructura no puede estar vacía en C porque la sintaxis lo prohíbe. Además, existe una restricción semántica que hace que el comportamiento no esté definido si una estructura no tiene un miembro con nombre:

struct-or-union-specifier:
  struct-or-union identifieropt { struct-declaration-list }
  struct-or-union identifier

struct-or-union:
  struct
  union

struct-declaration-list:
  struct-declaration
  struct-declaration-list struct-declaration

struct-declaration:
  specifier-qualifier-list struct-declarator-list ;

/* type-specifier or qualifier required here! */
specifier-qualifier-list:
  type-specifier specifier-qualifier-listopt
  type-qualifier specifier-qualifier-listopt

struct-declarator-list:
  struct-declarator
  struct-declarator-list , struct-declarator

struct-declarator:
  declarator
  declaratoropt : constant-expression

Si tú escribes

struct identifier { };

Le dará un mensaje de diagnóstico, porque viola las reglas sintácticas. Si tú escribes

struct identifier { int : 0; };

Luego, tiene una estructura no vacía sin miembros con nombre, lo que hace que el comportamiento no esté definido y no requiera un diagnóstico:

Si struct-declaration-list no contiene miembros con nombre, el comportamiento no está definido.

Tenga en cuenta que lo siguiente no está permitido porque un miembro de matriz flexible no puede ser el primer miembro:

struct identifier { type ident[]; };

  • pero el siguiente código funciona perfectamente con el compilador gcc e imprime cero ` struct abc { }; printf(“tamaño de la estructura vacía %d\n”, sizeof(struct abc));’

    – Vinit Dhatrak

    26 de octubre de 2009 a las 18:35

  • compilando con -ansi -pedantic da “main.c:2: advertencia: la estructura no tiene miembros”

    – Johannes Schaub – litb

    26/10/2009 a las 18:40

  • Las estructuras vacías son una extensión GCC.

    – Michael Burr

    26 de octubre de 2009 a las 18:41

  • No creo que el estándar C diga que se requiere un diagnóstico si viola una regla contenida solo en el BNF. En su mayor parte, se requiere un diagnóstico solo si se viola un “deberá” o “no deberá”, contenido con una cláusula de “restricciones”. En C++, la situación es ligeramente diferente (especifica que “El conjunto de reglas diagnosticables consta de todas las reglas sintácticas y semánticas de esta Norma Internacional…”

    – Jerry Ataúd

    26/10/2009 a las 18:50

  • C99 al menos dice: “Una implementación conforme producirá al menos un mensaje de diagnóstico (identificado de una manera definida por la implementación) si una unidad de traducción de preprocesamiento o una unidad de traducción contiene una violación de cualquier regla o restricción de sintaxis, …”

    – Johannes Schaub – litb

    26 de octubre de 2009 a las 18:51

avatar de usuario
miguel rebabas

La gramática C no permite que el contenido de un struct para estar vacío: tiene que haber al menos un campo de bits sin nombre o un miembro con nombre (en lo que respecta a la gramática, no estoy seguro de si una estructura que contiene solo un campo de bits sin nombre es válida).

El soporte para estructuras vacías en C es una extensión en GCC.

En C++ y la especificación de miembro de estructura/clase vacía está explícitamente permitida, pero el tamaño se define como 1, a menos que, como parte de la optimización de base vacía, el compilador pueda hacer que una clase base vacía no ocupe espacio en la clase derivada.

En C99: “Si struct-declaration-list no contiene miembros con nombre, el comportamiento no está definido”.

La sintaxis realmente no lo permite de todos modos, aunque no veo nada que diga que se requiere un diagnóstico, lo que lo vuelve a colocar en el campo de “comportamiento indefinido”.

  • “Miembros sin nombre” se refiere a la situación específica con bitfield sin nombre (ver la respuesta de litb arriba). Una estructura vacía simple (sin miembros en absoluto) es una violación de restricción, no UB.

    – Ant

    26 de octubre de 2009 a las 18:48

  • Lo acabo de releer y no veo tal restricción. Estoy viendo §6.7.2.1. Las restricciones que veo están en los párrafos 2 a 4. El párrafo 2 dice que el único tipo incompleto permitido es una matriz flexible. El párrafo 3 dice que un campo de bits puede tener un ancho de cero y ningún nombre, o un nombre y un ancho entre 1 y el tamaño del objeto subyacente. El párrafo 4 dice que el tipo subyacente de un campo de bits será _Bool, sin firmar o int (o cualquier otra cosa definida por la implementación).

    – Jerry Ataúd

    26 de octubre de 2009 a las 19:01

  • Es una violación de la regla de sintaxis, que exige un mensaje de diagnóstico.

    – Johannes Schaub – litb

    26 de octubre de 2009 a las 19:11

  • Si se trata de una violación de la regla de sintaxis, ciertamente requiere un diagnóstico, pero no puedo ver nada que diga que el BNF forma parte de las reglas de sintaxis. En su mayor parte, se tratan como no normativos (p. ej., el Apéndice A contiene todo el BNF, pero se etiqueta específicamente como “informativo”).

    – Jerry Ataúd

    26 de octubre de 2009 a las 19:20

  • @Jerry, las reglas dentro de las secciones de “Sintaxis” (como 6.7.2.1/1 en C99) son reglas de sintaxis, por supuesto. El Anexo A solo resume todas las reglas que ya se dan en la cláusula 6, por lo que es informativo.

    – Johannes Schaub – litb

    26 de octubre de 2009 a las 19:57

en VC 8 Da error si tratamos de obtener el tamaño de la estructura vacía, por el contrario en Linux con gcc da tamaño 1 porque usa la extensión gcc en lugar de la especificación del lenguaje c que dice que este es un comportamiento indefinido.

struct node
{
// empty struct.
};

int main()
{
printf("%d", sizeof(struct node));
return 0;
}

en windows vc 2005 Da error de compilación en linux con gcc da tamaño 1 porque la extensión gcc
http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Empty-Structures.html#Empty-Structures
(Como señaló Michael Burr)

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad