program - ¿Qué significa &(int){1} en C++?
stray in program arduino (2)
No es inmediatamente obvio, pero si miras el código circundante, queda claro para qué se usa y para qué tiene que ser.
Toma la dirección de una estructura anónima temporal que contiene un solo entero anónimo que se inicializa a través de un inicializador designado C99. La razón es que setsockopt
no quiere un entero, sino un puntero a él (o más bien, un puntero a algo y el tamaño de algo).
En otras palabras, es un truco muy bueno proporcionar un tipo de argumento entero (sin una variable temporal explícita) a una función que espera un puntero.
Entonces, es funcionalmente idéntico a:
int blah = 1;
setsockopt(..., &blah, ...);
... excepto que funciona sin introducir blah
.
Vi esto here y no sé lo que significa:
&(int) { 1 }
Pensé que era raro porque parece una sintaxis no válida. Está lanzando un ámbito de bloque (?) Con un 1 aleatorio en el medio (sin un punto y coma) y tomando la dirección. No tiene mucho sentido para mí. ¿Podrían ustedes iluminarme?
Lo probé con C ++ 11, por lo que compila:
auto a = &(int) { 1 };
Pero no tengo idea de qué hacer con la variable.
Por lo que puedo decir, esto es un literal compuesto , es una característica de C99, no es un C ++ estándar, pero tanto gcc como clang lo admiten como una extensión:
ISO C99 soporta literales compuestos. Un literal compuesto se parece a un reparto que contiene un inicializador. Su valor es un objeto del tipo especificado en la conversión, que contiene los elementos especificados en el inicializador; es un valor Como extensión, GCC admite literales compuestos en modo C90 y en C ++, aunque la semántica es algo diferente en C ++.
Normalmente, el tipo especificado es una estructura. Suponga que la estructura y la estructura se declaran como se muestra:
struct foo {int a; char b[2];} structure;
Aquí hay un ejemplo de cómo construir una estructura con un literal compuesto:
structure = ((struct foo) {x + y, ''a'', 0});
Esto es equivalente a escribir lo siguiente:
{ struct foo temp = {x + y, ''a'', 0}; struct
En este caso, el tipo de a
puntero a int. Esperemos que este fue originalmente un código C ya que el documento gcc dice:
En C, un literal compuesto designa un objeto sin nombre con una duración de almacenamiento estática o automática. En C ++, un literal compuesto designa un objeto temporal, que solo vive hasta el final de su expresión completa.
y por lo tanto, tomar la dirección en C ++ es probablemente una mala idea ya que la vida útil del objeto termina al final de la expresión completa. Aunque podría haber sido un código C ++ que se basó en un comportamiento indefinido.
Este es uno de esos casos en los que usar las -pedantic correctas realmente ayuda mucho, tanto en gcc como en clang usando -pedantic producirá una advertencia y un error, por ejemplo, gcc dice:
warning: ISO C++ forbids compound-literals [-Wpedantic]
auto a = &(int) { 1 };
^
error: taking address of temporary [-fpermissive]
Si usamos -fpermissive
es gcc, sí permite que se compile este código. No puedo usar el -Wno-address-of-temporary
para construir este código con ninguna bandera en las versiones modernas, aunque las versiones anteriores parecen permitirlo usando -Wno-address-of-temporary
. Me pregunto si gcc permite esto como un remanente de una extensión antigua .
Tenga en cuenta que la pregunta Cryptic struct definition en C tiene un uso bastante interesante ( dependiendo de su definición de interesante ) de literales compuestos.
Asumiendo que el cisma es correcto y esta pregunta es la fuente original, entonces el uso en ese código en el ejemplo:
if (setsockopt(server_connection.socket, SOL_SOCKET, SO_REUSEADDR, &(int) { 1 }, sizeof(int)) < 0) {
es un uso válido tanto en C99 como en C ++.