Inicializar una estructura a 0

5 minutos de lectura

avatar de usuario
Daan Timmer

Si tengo una estructura como esta:

typedef struct
{
    unsigned char c1;
    unsigned char c2;
} myStruct;

¿Cuál sería la forma más fácil de inicializar esta estructura a 0? ¿Bastaría con lo siguiente?

myStruct _m1 = {0};

o ¿Necesitaría iniciar explícitamente cada miembro en 0?

myStruct _m2 = {0,0};

  • Nota: si la estructura tiene bytes de relleno (debido a la alineación), ninguno de estos garantiza que se inicialicen. Puede ser importante al escribir la estructura en almacenamiento externo, red o comparar con memcmp. En tales casos se debe utilizar memset.

    – Yakov Galka

    29 de enero de 2021 a las 3:18


avatar de usuario
Guardar

El primero es el más fácil (implica menos tipeo), y se garantiza que funcione, todos los miembros se establecerán en 0[Ref 1].
El segundo es más legible.

La elección depende de la preferencia del usuario o de lo que exige su estándar de codificación.

[Ref 1] Referencia C99 Estándar 6.7.8.21:

Si hay menos inicializadores en una lista entre llaves que elementos o miembros de un agregado, o menos caracteres en una cadena literal utilizada para inicializar una matriz de tamaño conocido que elementos en la matriz, el resto del agregado debe inicializarse implícitamente igual que los objetos que tienen una duración de almacenamiento estática.

Buena lectura:

C y C++: inicialización parcial de la estructura automática

  • Además, estoy usando = {}; Sin embargo, no estoy seguro de si esto es válido.

    – William Entriken

    19 de marzo de 2015 a las 21:09

  • @FullDecent llaves vacías para la inicialización es una extensión GNU.

    – a3f

    12/09/2015 a las 18:13


  • @alias65536 La pregunta está etiquetada como C, no C++.

    – a3f

    21 de julio de 2017 a las 17:27

  • Recibí un error: “faltan llaves alrededor del inicializador [-Werror=missing-braces]”probablemente debido a una matriz de miembros:/

    – DrumM

    14 de febrero de 2018 a las 11:07


  • @Edenia. Estoy en desacuerdo. ya se que foo = {0} medio. Si yo viera foo = ZERO_FULLtendría que buscar la definición de ZERO_FULL.

    –Andrew Bainbridge

    24 de julio de 2018 a las 14:51


avatar de usuario
Basile Starynkevitch

Si los datos son una variable estática o global, se rellenan con ceros de forma predeterminada, así que simplemente declárelos myStruct _m;

Si los datos son una variable local o una zona asignada al montón, bórrelos con memset me gusta:

memset(&m, 0, sizeof(myStruct));

Compiladores actuales (por ejemplo, versiones recientes de gcc) optimizar eso bastante bien en la práctica. Esto funciona solo si todos los valores cero (incluidos los punteros nulos y el punto flotante cero) se representan como todos los bits cero, lo cual es cierto en todas las plataformas que conozco (pero el C estándar permite implementaciones donde esto es falso; No conozco tal implementación).

Tal vez podrías codificar myStruct m = {}; o myStruct m = {0}; (incluso si el primer miembro de myStruct no es un escalar).

Mi sensación es que usando memset para las estructuras locales es lo mejor, y transmite mejor el hecho de que en tiempo de ejecución hay que hacer algo (mientras que, por lo general, los datos globales y estáticos pueden entenderse como inicializados en tiempo de compilación, sin ningún costo en tiempo de ejecución).

  • No hay garantía de que establecer todos los bytes de la estructura en 0 será equivalente a inicializar todos los miembros de la estructura con 0 aunque. En muchas plataformas esto será cierto, pero no universalmente.

    – Sander de Dycker

    22 de junio de 2012 a las 7:55

  • ¿Puedes compartir un ejemplo, Sander? Curiosidad genuina. (Obviamente, no universalmente cierto no significa necesariamente que haya una excepción fácil de explicar, pero si la hay…)

    –Steven Fisher

    22 de junio de 2012 a las 7:57

  • los C El estándar permite que el puntero nulo (o un número de punto flotante cero) se represente en la memoria por algo más que todos los bits cero. Muy pocas implementaciones extrañas están haciendo eso (no puedo nombrar ninguna).

    – Basile Starynkevitch

    22 de junio de 2012 a las 7:59


  • -1, es posible que encuentre fea la inicialización sobre la que OP pregunta, pero es exactamente lo que prevé el estándar y todos los compiladores pueden optimizarlo fácilmente. Entonces, la forma {} no es C válido pero solo está disponible en C++.

    – Jens Gusted

    22 de junio de 2012 a las 8:08

  • @Steven: solo puedo pensar en plataformas oscuras y/o antiguas. Las preguntas frecuentes de C tienen una lista de plataformas que tenían una NULL puntero eso no fue todo 0 pedacitos: c-faq.com/null/mahexamp.html. Y luego existe la posibilidad de que la plataforma no esté usando IEEE 754 para representar valores de punto flotante, sino que use alguna otra representación que no tiene un todo. 0 poco 0.0 valor – pero es cierto que no conozco tal plataforma.

    – Sander de Dycker

    22 de junio de 2012 a las 8:32

avatar de usuario
dirkgently

Ver §6.7.9 Inicialización:

21 Si hay menos inicializadores en una lista entre llaves que elementos o miembros de un agregado, o menos caracteres en una cadena literal utilizada para inicializar una matriz de tamaño conocido que elementos en la matriz, el resto del agregado se inicializará implícitamente igual que los objetos que tienen una duración de almacenamiento estática.

Entonces, sí, ambos funcionan. Tenga en cuenta que en C99 también se puede usar una nueva forma de inicialización, llamada inicialización designada:

myStruct _m1 = {.c2 = 0, .c1 = 1};

  • En particular, esto ya es C89: open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf#page=139 (Importante para objetivos específicos de procesamiento de señales)

    – Tobías

    2 de julio de 2019 a las 14:55


  • Pero tenga en cuenta que funciona intuitivamente para {0} pero no tan claro si, por ejemplo, hace {1}. Es fácil pensar que establecería todo en 1, pero establecerá solo el primero en 1 e inicializará implícitamente el resto, por lo que es probable que termine con 1,0.

    – Zitrax

    12 de febrero de 2021 a las 11:39

avatar de usuario
gibones

También pensé que esto funcionaría, pero es engañoso:

myStruct _m1 = {0};

Cuando probé esto:

myStruct _m1 = {0xff};

Solo el primer byte se configuró en 0xfflos restantes se establecieron en 0. Así que no me acostumbraría a usar esto.

¿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