Que signifie & (int) {1} en C ++?

J’ai vu ça ici et je ne sais pas ce que ça veut dire:

&(int) { 1 } 

Je pensais que c’était bizarre parce que cela semblait être une syntaxe invalide. Il lance une scope de bloc (?) Avec un 1 aléatoire au milieu (sans point-virgule) et prend l’adresse. Cela n’a pas beaucoup de sens pour moi. Pourriez-vous m’éclairer?

Essayé avec C ++ 11, donc il comstack:

 auto a = &(int) { 1 }; 

Mais je ne sais pas quoi faire avec la variable.

Autant que je sache, il s’agit d’un littéral composé , il s’agit d’une fonctionnalité C99, ce n’est pas du C ++ standard, mais gcc et clang le prennent en charge comme une extension:

ISO C99 prend en charge les littéraux composés. Un littéral composé ressemble à un casting contenant un initialiseur. Sa valeur est un object du type spécifié dans la conversion, contenant les éléments spécifiés dans l’initialiseur. c’est une lvalue. En tant qu’extension, GCC prend en charge les littéraux composés en mode C90 et en C ++, bien que la sémantique soit quelque peu différente en C ++.

Généralement, le type spécifié est une structure. Supposons que struct foo et la structure sont déclarés comme indiqué:

  struct foo {int a; char b[2];} structure; 

Voici un exemple de construction d’un struct foo avec un littéral composé:

  structure = ((struct foo) {x + y, 'a', 0}); 

Cela équivaut à écrire ce qui suit:

  { struct foo temp = {x + y, 'a', 0}; struct 

Dans ce cas, le type d’ a pointeur serait int. Espérons que c’était à l’origine du code C, comme le dit le document gcc:

En C, un littéral composé désigne un object sans nom avec une durée de stockage statique ou automatique. En C ++, un littéral composé désigne un object temporaire, qui ne vit que jusqu’à la fin de sa pleine expression.

et donc prendre l’adresse en C ++ est probablement une mauvaise idée car la durée de vie de l’object est terminée à la fin de l’expression complète. Bien que cela aurait pu être du code C ++ qui reposait simplement sur un comportement indéfini.

C’est l’un des cas où l’utilisation des drapeaux corrects aide beaucoup, que ce soit en gcc ou en clang, utiliser -pedantic produira un avertissement et une erreur, par exemple gcc dit:

 warning: ISO C++ forbids compound-literals [-Wpedantic] auto a = &(int) { 1 }; ^ error: taking address of temporary [-fpermissive] 

si nous utilisons -fpermissive est gcc, cela permet effectivement à ce code de comstackr. Je ne peux pas obtenir clang pour construire ce code avec aucun indicateur dans les versions modernes bien que les anciennes versions semblent le permettre en utilisant -Wno-address-of-temporary . Je me demande si gcc permet cela comme un vestige d’une ancienne extension .

Notez que la question Définition de la structure cryptique en C a une utilisation très intéressante (en fonction de votre définition d’intéressant ) des littéraux composés.

En supposant que Schism soit correct et que cette question soit la source d’origine, son utilisation dans le code de l’exemple est la suivante:

 if (setsockopt(server_connection.socket, SOL_SOCKET, SO_REUSEADDR, &(int) { 1 }, sizeof(int)) < 0) { 

est une utilisation valide en C99 et en C ++.

Ce n’est pas immédiatement évident, mais si vous regardez le code qui l’entoure, vous verrez clairement à quoi il sert et ce qu’il doit être.

Il prend l’adresse d’une structure anonyme anonyme contenant un seul entier anonyme qui est initialisée via un initialiseur désigné par C99. La raison en est que setsockopt ne veut pas d’un entier, mais un pointeur sur celui-ci (ou plutôt, un pointeur sur quelque chose et la taille de quelque chose).

En d’autres termes, il est très astucieux de fournir un type d’argument entier (sans variable temporaire explicite) à une fonction qui attend un pointeur.

Donc, son fonctionnement est identique à:

 int blah = 1; setsockopt(..., &blah, ...); 

… sauf que cela fonctionne sans introduire de blah .