Encontré este fragmento de código en GitHub pero no lo entendí del todo:
#define lambda(ret_type, _body) ({ ret_type _ _body _; })
Entonces:
int (*max)(int, int) = lambda(int,
(int x, int y) {
return x > y ? x : y;
});
int max_value = max(1, 2);
// max_value is 2
¿Qué están haciendo los guiones bajos dentro #define
y cómo devuelve un puntero de función?
gcc -E
) para ver qué hace?Respuestas:
Usando esta macro,
se expande a:
En las llaves, esto usa GCC funciones anidadas para crear una función que realice la operación deseada. Dentro del alcance interno, tiene el nombre
_
.Luego, como lo señaló Interjay, las expresiones de declaración de GCC se utilizan las . Efectivamente, la función
_
se asigna al punteromax
.Si no se usa una macro de este tipo, esto podría escribirse de manera diferente y usarse como:
Los tres métodos se pueden comparar en este ejemplo de código .
fuente
max(4, -30);
lugar deapply_binary_op(max, 4, -30);
?Esto se llama una expresión de instrucción y crea una "lambda" (o función anidada ) y le devuelve un puntero. Es GNU C específico.
La macro se expande a:
Al
_
final es como areturn
.El guión bajo es en realidad el nombre de la función que se crea y "devuelve". Se usa porque es un identificador de uso poco frecuente (por una buena razón;
_
posiblemente sea el identificador menos descriptivo posible).La razón por la que se usa la expresión de la declaración es
_
que no se definirá después de que salga el alcance de la expresión de la declaración.Entonces, pasando por la macro:
ret_type
es el tipo de retorno de la "lambda"._
es el nombre de la función utilizada en su interior porque es un nombre de identificador poco común._body
consiste en los argumentos y el cuerpo de la función. El final_
"devuelve" la "lambda".Este código se encuentra en Let's Destroy C (que es un nombre apropiado). No deberías usarlo. Hará que su código funcione solo en compiladores que admitan extensiones GNU C. En cambio, solo escribe una función o macro.
Si usa muchas construcciones como esta o desea más funciones, sugiero usar C ++. Con C ++ puedes hacer algo similar a esto y tener un código portátil.
fuente