2011-01-24 22 views
7

tengo el siguiente código en un archivo de C++: advertencias¿Cómo debo inicializar correctamente una estructura C desde C++?

#include <sys/socket.h> 

// ... 
void someFunc() { 
    struct msghdr msg = {0}; // <<< Uninitialized member here 
} 

Cuando compilo con g++ usando -Wall -Wextra, me sale:

error: missing initializer for member 'msghdr::msg_namelen' 
...same for several other fields 

Mi problema es el siguiente: No puedo inicializar explícitamente todos los campos, porque no sé qué campos existirán (multiplataforma) en un struct msghdr. La estructura no tiene un constructor predeterminado, ya que es una estructura C Tenía la impresión de que el formulario = {0} conducía a cero inicialización de todos los campos (lo que estaría bien para mí), pero el mensaje de error g++ sugiere que no.

¿Cuáles son mis opciones aquí?

+0

posible duplicado de [¿Por qué el compilador lanza esta advertencia: "falta el inicializador"? ¿No se inicializó la estructura?] (Http://stackoverflow.com/questions/1538943/why-is-the-compiler-throwing-this-warning-missing-initializer-isnt-the-stru) – ergosys

Respuesta

8
void someFunc() 
{ 
    msghdr msg = {}; // <<< All members zero-initialized 
} 

El g ++ -Wextra nivel de advertencia es mi humilde opinión no es muy útil.

El código que tiene también está formalmente bien para una "C struct", en estándar conocida como POD (Plain Old Data). Pero su código inicializa explícitamente al primer miembro con 0. Eso no necesariamente funcionará para un agregado que no sea POD, p. Ej. con un std::string como primer miembro, mientras que el {} puro también funcionará para eso.

De paso, a menudo un POD como el que está tratando tiene un número de bytes como primer miembro, y luego puede hacer como & hellip;

void foo() 
{ 
    SomePODStruct o = {sizeof(o)}; // The other members zero-initialized. 
} 

quizás añadir un STATIC_ASSERT que el miembro de cuenta de bytes es primero (en la posición 0).

Saludos & HTH,

+1

No estoy de acuerdo con la oración _El nivel de advertencia de g ++ -Wextra no es muy útil_. – peoro

+1

@ peoro: OK. Agregué un "IMHO".:-) –

+0

Gracias por la entrada Alf, es bueno saber que es '-Wextra' que está roto y no mi comprensión de C++ :-) –

4

Esto debería funcionar:

memset(&msg, 0, sizeof(msg)); 
+0

corrige tu error tipográfico y Eliminaré mi respuesta, ¡me ganaste por segundos! :) – Nim

1

Si no se puede vivir con la advertencia y/o no desea desactivar la advertencia, entonces yo creo que tendrá que ser la inicialización explícita a través de, por ejemplo, memset:

memset(&msg, 0, sizeof(msg)); 
0

tal vez si usted no desea utilizar constructor por defecto puede simplemente usar las funciones de preprocesador como:.

#ifdef LINUX 
//init for linux 
#endif 

#ifdef WINDOWS 
//init for windows 
#endif 

y así sucesivamente

+0

Lo siento, no entiendo cómo esto inicializará la estructura. La definición de estructura está fuera de mi control (estando en 'socket.h'). ¿Puedes dar un ejemplo de cómo se vería la inicialización de la estructura en tu solución propuesta? –

+0

Quise decir que sabes cómo se ve la estructura para cada plataforma. Y puede inicializarlo para cada plataforma porque conoce todos los campos. Por lo tanto, si en alguna parte de la aplicación va a escribir, por ejemplo, #define LINUX, el preprocesador del código agregará una parte de LINUX y se ejecutará. En este caso, su función será diferente para la plataforma diferente. http://stackoverflow.com/questions/2989810/which-cross-platform-preprocessor-defines-win32-or-win32-or-win32 - puede ser útil – Andrew

+0

OK, eso tiene sentido, gracias por aclarar. –

2

La bandera de advertencia específica Esto causa esto es -Wmissing-field-initializers, que se enciende como parte de -Wextra. La forma más sencilla de evitar esta advertencia (falsa) es, por lo tanto, usar -Wno-missing-field-initializers.

Cuestiones relacionadas