Cuando {0}
se usa para inicializar un objeto, ¿qué significa? No puedo encontrar ninguna referencia a {0}
ninguna parte y, debido a las llaves, las búsquedas de Google no son útiles.
Código de ejemplo:
SHELLEXECUTEINFO sexi = {0}; // what does this do?
sexi.cbSize = sizeof(SHELLEXECUTEINFO);
sexi.hwnd = NULL;
sexi.fMask = SEE_MASK_NOCLOSEPROCESS;
sexi.lpFile = lpFile.c_str();
sexi.lpParameters = args;
sexi.nShow = nShow;
if(ShellExecuteEx(&sexi))
{
DWORD wait = WaitForSingleObject(sexi.hProcess, INFINITE);
if(wait == WAIT_OBJECT_0)
GetExitCodeProcess(sexi.hProcess, &returnCode);
}
Sin él, el código anterior se bloqueará en tiempo de ejecución.
Una cosa a tener en cuenta es que esta técnica no establecerá bytes de relleno en cero. Por ejemplo:
No es lo mismo que:
En el primer caso, los bytes de relleno entre cy i no se inicializan. ¿Por qué te importaría? Bueno, si está guardando estos datos en el disco o enviándolos a través de una red o lo que sea, podría tener un problema de seguridad.
fuente
Tenga en cuenta que un inicializador agregado vacío también funciona:
fuente
En respuesta a por qué se
ShellExecuteEx()
está bloqueando: suSHELLEXECUTEINFO
estructura "sexi" tiene muchos miembros y solo está inicializando algunos de ellos.Por ejemplo, el miembro
sexi.lpDirectory
podría estar apuntando a cualquier parte, peroShellExecuteEx()
aún intentará usarlo, por lo tanto, obtendrá una infracción de acceso a la memoria.Cuando incluye la línea:
antes del resto de la configuración de su estructura, le está diciendo al compilador que ponga a cero todos los miembros de la estructura antes de inicializar los específicos que le interesan.
ShellExecuteEx()
Sabe que sisexi.lpDirectory
es cero, debería ignorarlo.fuente
También lo uso para inicializar cadenas, por ejemplo.
fuente
{0}
es un inicializador válido para cualquier tipo (objeto completo), tanto en C como en C ++. Es un idioma común usado para inicializar un objeto a cero ( sigue leyendo para ver qué significa eso).Para los tipos escalares (tipos aritméticos y de puntero), los corchetes son innecesarios, pero están explícitamente permitidos. Citando el borrador N1570 del estándar ISO C, sección 6.7.9:
Inicializa el objeto a cero (
0
para enteros,0.0
para coma flotante, un puntero nulo para punteros).Para los tipos no escalares (estructuras, matrices, uniones),
{0}
especifica que el primer elemento del objeto se inicializa a cero. Para estructuras que contienen estructuras, matrices de estructuras, etc., esto se aplica de forma recursiva, por lo que el primer elemento escalar se establece en cero, según corresponda para el tipo. Como en cualquier inicializador, cualquier elemento no especificado se establece en cero.Se pueden omitir llaves intermedias (
{
,}
); Por ejemplo, ambos son válidos y equivalentes:Es por eso que no tiene que escribir, por ejemplo,
{ { 0 } }
para un tipo cuyo primer elemento no es escalar.Así que esto:
es una forma abreviada de inicializar
obj
a cero, lo que significa que cada subobjeto escalar deobj
se establece en0
si es un entero,0.0
si es un punto flotante o un puntero nulo si es un puntero.Las reglas son similares para C ++.
En su caso particular, dado que está asignando valores
sexi.cbSize
, etc., está claro queSHELLEXECUTEINFO
es una estructura o un tipo de clase (o posiblemente una unión, pero probablemente no), por lo que no todo esto se aplica, pero como dije{ 0 }
es algo común modismo que se puede usar en situaciones más generales.Esto no es (necesariamente) equivalente a usar
memset
para establecer la representación del objeto en todos-bits-cero. Ni el punto flotante0.0
ni un puntero nulo se representan necesariamente como todos los bits cero, y un{ 0 }
inicializador no establece necesariamente los bytes de relleno en ningún valor en particular. Sin embargo, en la mayoría de los sistemas, es probable que tenga el mismo efecto.fuente
{0}
no es un inicializador válido para un objeto sin que el constructor lo acepte0
; ni para un agregado cuyo primer elemento es como tal (o un agregado sin elementos)Ha pasado un tiempo desde que trabajé en c / c ++ pero IIRC, el mismo acceso directo también se puede usar para matrices.
fuente
Siempre me he preguntado por qué deberías usar algo como
Aquí hay un caso de prueba para explicar:
check.c
Compilo
gcc -O2 -o check check.c
y luego envío la tabla de símbolos conreadelf -s check | sort -k 2
(esto es con gcc 4.6.3 en ubuntu 12.04.2 en un sistema x64). Extracto:La parte importante aquí es, eso
my_zero_struct
es después__bss_start
. La sección ".bss" en un programa en C es la sección de memoria que se establece en cero antes demain
llamarse ver wikipedia en .bss .Si cambia el código anterior a:
Luego, el ejecutable "check" resultante se ve exactamente igual al menos con el compilador gcc 4.6.3 en ubuntu 12.04.2; la
my_zero_struct
sigue en la.bss
sección y por lo tanto, se inicializará automáticamente a cero, antes demain
que se llama.Sugerencias en los comentarios, que un
memset
podría inicializar la estructura "completa" tampoco es una mejora, porque la.bss
sección se borra completamente, lo que también significa que la estructura "completa" se establece en cero.Que podría ser que el lenguaje estándar C no menciona nada de esto, pero en un verdadero compilador C mundo que nunca han visto un comportamiento diferente.
fuente
Es el azúcar sintáctico para inicializar toda su estructura a valores vacíos / cero / nulos.
Versión larga
Version corta
¿No fue mucho más fácil?
También es bueno porque:
ZeroMemory
fuente
{0} es una matriz anónima que contiene su elemento como 0.
Esto se usa para inicializar uno o todos los elementos de la matriz con 0.
por ejemplo, int arr [8] = {0};
En este caso, todos los elementos de arr se inicializarán como 0.
fuente
{0}
No es una matriz anónima. Ni siquiera es una expresión. Es un inicializador.