c++11 funciones - ¿Cómo es "int main(){(([](){})())}" válido C++?




lambda examples (2)

El código esencialmente llama a un lambda vacío.

Comencemos por el principio: [](){} es una expresión lambda vacía.

Luego, en C y C ++, puedes envolver expresiones en parens y se comportan exactamente igual que si estuvieran escritas sin ellas, así que eso es lo que hace el primer par de parens alrededor de la lambda. Ahora estamos en ([](){}) .

Luego, () después de la primera envoltura de parens llama a la lambda (vacía). Ahora estamos en ([](){})()

La expresión completa está envuelta en parens nuevamente y obtenemos (([](){})()) .

Por fin ; termina la declaración. Llegamos a (([](){})()); .

† Hay algunos casos de esquina al menos en C ++, como con T a_var; hay una diferencia entre decltype(a_var) y decltype((a_var)) .

Recientemente me encontré con la siguiente pieza de código esotérico.

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

Reformatéelo de la siguiente manera para hacerlo más legible:

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

Pero no puedo entender cómo (([](){})()) es un código válido.

  • No parece la sintaxis de puntero de función.
  • No puede ser un truco de sobrecarga del operador. El código se compila como es.

Google no ayudó mucho con esta búsqueda de todos los símbolos. Pero se compila en Visual Studio 2010 y no produce nada. No hubo errores, ni advertencias. Así que parece un código válido.

Nunca he visto ningún código válido que sea tan extraño fuera de los punteros de función de Javascript y C.

¿Alguien puede explicar cómo esto es válido C ++?


Como esto está etiquetado como "incrustado", asumiré que estás usando un microcontrolador. Todas las sugerencias anteriores son válidas y de trabajo (lectura-modificación-escritura, uniones, estructuras, etc.).

Sin embargo, durante un combate de depuración basada en el osciloscopio, me sorprendió descubrir que estos métodos tienen una sobrecarga considerable en los ciclos de la CPU en comparación con la escritura de un valor directamente en los registros PORTnSET / PORTnCLEAR de los micrófonos, lo que marca una diferencia real cuando hay bucles ajustados / altos -la frecuencia de los pines de conmutación de ISR.

Para aquellos que no están familiarizados: en mi ejemplo, el micro tiene un registro general de estado de PIN que refleja los pines de salida, por lo que hacer PORTn | = BIT_TO_SET da como resultado una lectura-modificación-escritura en ese registro. Sin embargo, los registros PORTnSET / PORTnCLEAR toman un '1' para significar "haga este bit 1" (SET) o "haga este bit cero" (CLEAR) y un '0' significa "dejar el pin solo". por lo tanto, termina con dos direcciones de puerto dependiendo de si está configurando o borrando el bit (no siempre es conveniente) pero una reacción mucho más rápida y un código ensamblado más pequeño.





c++ c++11 lambda syntax