Estoy creando una especie de interfaz para un programa. Para lanzar el programa estoy usando la llamada CreateProcess()
, que entre otras cosas recibe un puntero a una STARTUPINFO
estructura. Para inicializar la estructura que solía hacer:
STARTUPINFO startupInfo = {0}; // Or even '\0'.
startupInfo.cb = sizeof(startupInfo);
Al compilar el programa con GCC que habilita estos conjuntos de advertencias -Wall -Wextra
, me da una advertencia que dice que falta un inicializador que apunta a la primera línea.
warning: missing initializer
warning: (near initialization for 'startupInfo.lpReserved')
Así que terminé haciendo:
STARTUPINFO startupInfo;
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
Y de esta forma el compilador no da ninguna advertencia. La pregunta es, ¿cuál es la diferencia entre estas formas de inicializar una estructura? Usando el primer método, ¿no se inicializa la estructura? ¿Cuál recomendarías?
struct struct_with_four_fields x = {1, 2, 3};
donde solo se inicializan 3 de 4 miembros.{ 0 }
es un idioma común y bien definido para inicializar todos los miembros a cero (definido de forma recursiva para cada submiembro), por lo que las versiones posteriores de gcc se han modificado para no advertir sobre ese caso en particular.obj = {0};
del mensaje al que se vinculó no es C válida y gcc 4.8.2 la rechaza como un error de sintaxis. Si está compilando como C ++, recuerde que es un lenguaje diferente y gcc usa una interfaz diferente; Las correcciones en el compilador C de gcc pueden aplicarse o no a g ++.Respuestas:
GCC está siendo demasiado paranoico, sin una buena razón en mi opinión, pero es cierto que los mantenedores de GCC saben mucho más sobre los matices de C que yo.
Vea este pequeño hilo de discusión sobre el problema en la lista de correo de GCC:
Sin embargo, en pocas palabras: inicializar la estructura con solo
{0}
, de hecho, inicializará todo en cero.El estándar C99 dice lo siguiente en 6.7.8 / 21 "Inicialización - Semántica":
C90 dice esencialmente lo mismo en 6.5.7 con una redacción un poco diferente (en otras palabras, C99 no agregó nada nuevo aquí).
También tenga en cuenta que en C ++ esto se extendió para que un conjunto vacío de llaves, "
{}
", realizara la inicialización de valor en un objeto porque había situaciones (como plantillas) en las que ni siquiera sabría cuáles son los miembros o cuántos miembros de un tipo podría tener. Entonces, no solo es una buena práctica, sino que a veces es necesario tener una lista de inicializadores más corta que la cantidad de miembros que podría tener un objeto.fuente
-Wno-missing-field-initializers
y-Wno-missing-braces
para que GGC dejara de quejarse de que yo ponía= {0};
para mis estructuras. ¿Alguien sabe si al desactivar estas advertencias se perderán las advertencias para otras cosas que no sean= {0};
estructuras?mingw32-g++.exe (GCC) 4.7.2
y obteniendo esta advertencia en el idioma anterior (incluso el caso exacto deSTARTUPINFO
).{}
o los{0}
inicializadores en mis clases de C ++: /Esto se puede arreglar fácilmente para GCC en programas C ++ inicializando la estructura como
fuente
Solicitó tantas advertencias como sea posible utilizando
-Wall -Wextra
.En este caso, recibe una advertencia que le dice que no especificó todos los campos, lo cual es perfectamente válido, pero podría haber sido no intencional.
Puede suprimir esta advertencia agregando
-Wno-missing-field-initializers
fuente
Esta página web analiza el problema subyacente con gran detalle: http://ex-parrot.com/~chris/random/initialise.html
Como solución temporal, mi solución actual es suprimir selectivamente esta advertencia:
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-field-initializers" STARTUPINFO startupInfo = {0}; #pragma clang diagnostic pop
Lamentablemente, esto solo funciona en clang y no parece funcionar en GCC.
fuente
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
aceptado por el compilador GCC 4.2.1 pero no hago nada. no#pragma clang diagnostic ignored "-Wmissing-field-initializers"
. Probablemente debería comprobar si este es el caso.En C ++ puede utilizar
boost::initialized_value
para deshacerse de esta advertencia. Tengo las advertencias desactivadas paraboost
; así que no sé si esto causaría otras advertencias en su caso. De esta manera, no es necesario que desactive la advertencia.Ejemplo:
fuente