web-dev-qa-db-fra.com

Comment "int main () {(([] () {}) ());}" est-il valide en C ++?

Je suis récemment tombé sur le code ésotérique suivant.

int main(){(([](){})());}

Reformatez-le comme suit pour le rendre plus lisible:

int main(){
    (([](){})());   //  Um... what?!?!
}

Mais je ne peux pas comprendre comment (([](){})()) est un code valide.

  • Cela ne ressemble pas à la syntaxe du pointeur de fonction.
  • Ce ne peut pas être une astuce de surcharge de l'opérateur. Le code est compilé tel quel.

Google n'a pas beaucoup aidé avec cette recherche de symboles. Mais il compile dans Visual Studio 2010 et ne génère rien. Il n'y avait aucune erreur, et aucun avertissement. Cela ressemble donc à un code valide.

Je n'ai jamais vu de code valide aussi bizarre en dehors de Javascript et pointeurs de fonction C .

Quelqu'un peut expliquer comment cela est valide C++?

259
Mysticial

Le code appelle essentiellement un lambda vide.

Commençons par le début: [](){} est un vide expression lambda .

Ensuite, en C et C++, vous pouvez envelopper des expressions entre parenthèses et elles se comportent exactement de la même manière. comme s'ils étaient écrits sans eux, c'est donc ce que fait la première paire de parens autour du lambda. Nous sommes maintenant à ([](){}).

Ensuite, () Après le premier bouclage appelle le lambda (vide). Nous sommes maintenant à ([](){})()

Toute l'expression est à nouveau entourée de parenthèses et nous obtenons (([](){})()).

Enfin, ; Termine l'instruction. Nous arrivons à (([](){})());.


† Il y a des angles au moins en C++, comme avec T a_var;il y a une différence entre decltype(a_var) et decltype((a_var)) .

272
Xeo