¿Por qué el compilador lanza esta advertencia: "falta el inicializador"? ¿No se inicializó la estructura?
winapi gcc (5)
En C ++ puedes usar boost::initialized_value
para deshacerte de esta advertencia. Tengo advertencias desactivadas para boost
; así que no sé si esto causaría otras advertencias en su caso. De esta manera, no tiene que deshabilitar la advertencia.
Ejemplo:
T bla = boost::initialized_value;
Estoy creando una especie de frontend para un programa. Para iniciar el programa, estoy usando la llamada CreateProcess()
, que entre otras cosas recibe un puntero a una estructura STARTUPINFO
. Para inicializar la estructura que solía hacer:
STARTUPINFO startupInfo = {0}; // Or even ''/0''.
startupInfo.cb = sizeof(startupInfo);
Cuando compilo el programa con GCC habilitando estos conjuntos de advertencias -Wall -Wextra
me da una advertencia diciendo 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 manera 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 inicializó la estructura? ¿Cuál recomendarías?
Esta página web analiza el problema subyacente con gran detalle: http://ex-parrot.com/~chris/random/initialise.html
Como solución alternativa, 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.
Esto se puede solucionar fácilmente para GCC en programas C ++ inicializando la estructura como
STARTUPINFO startupInfo = STARTUPINFO();
- Acabo de hacer exactamente esto hace unos días
GCC simplemente está siendo demasiado paranoico, sin una buena razón en mi opinión, pero luego 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:
- http://gcc.gnu.org/ml/gcc-bugs/1998-07/msg00031.html
- http://gcc.gnu.org/ml/gcc-bugs/1998-07/msg00059.html
- http://gcc.gnu.org/ml/gcc-bugs/1998-07/msg00128.html
En resumen: inicializar la estructura con solo {0}
de hecho no iniciará todo.
El estándar C99 dice lo siguiente en 6.7.8 / 21 "Initialization - Sematics":
Si hay menos inicializadores en una lista adjunta que no hay elementos o miembros de un agregado, o menos caracteres en un literal de cadena utilizado para inicializar una matriz de tamaño conocido que no hay elementos en la matriz, el resto del agregado inicializarse implícitamente de la misma manera que los objetos que tienen una duración de almacenamiento estática.
C90 dice esencialmente lo mismo en 6.5.7 con una redacción un poco diferente (en otras palabras, C99 no agregó algo 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 valores en un objeto porque había situaciones (como plantillas) en las que ni siquiera sabía qué miembros o cuántos miembros un tipo podría tener. Por lo tanto, no solo es una buena práctica, sino que a veces es necesario contar con una lista de inicializadores que sea más corta que la cantidad de miembros que un objeto pueda tener.
Usted pidió tantas advertencias como fue posible usando -Wall -Wextra.
En este caso, aparece una advertencia que le indica que no especificó todos los campos, lo cual es perfectamente válido, pero podría haber sido involuntario.
Puede suprimir esta advertencia agregando -Wno-missing-field-initializers