stray program error c++ c99

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 ++.