Encontrei este código no GitHub, mas não o entendi:
#define lambda(ret_type, _body) ({ ret_type _ _body _; })
Então:
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
O que os sublinhados estão fazendo dentro do #define
e como ele retorna um ponteiro de função?
gcc -E
) para ver o que ela faz?Respostas:
Usando essa macro,
expande para:
Nos chavetas, isso usa as funções aninhadas do GCC para criar uma função que executa a operação desejada. No âmbito interno, que tem o nome
_
.Então, como observado pelo interjay, os GCCs Expressões de declaração são usadas. Efetivamente, a função
_
é atribuída ao ponteiromax
.Se essa macro não estiver sendo usada, isso poderá ser escrito de forma diferente e usado como:
Os três métodos podem ser comparados neste exemplo de código .
fonte
max(4, -30);
vez deapply_binary_op(max, 4, -30);
?Isso é chamado de expressão de instrução e cria uma "lambda" (ou função aninhada ) e retorna um ponteiro para ela. É específico do GNU C.
A macro se expande para:
O
_
no final é como areturn
.O sublinhado é realmente o nome da função criada e "retornada". É usado porque é um identificador pouco utilizado (por boas razões;
_
é possivelmente o identificador menos descritivo possível).O motivo pelo qual a expressão de instrução é usada é que
_
não será definido após a saída do escopo da expressão de instrução.Então, passando pela macro:
ret_type
é o tipo de retorno do "lambda"._
é o nome da função usada nela porque é um nome de identificador incomum._body
consiste nos argumentos e corpo da função. A trilha_
"retorna" o "lambda".Este código é encontrado em Let's Destroy C (que é um nome apropriado). Você não deveria usá-lo. Isso fará com que seu código funcione apenas em compiladores que suportam extensões GNU C. Em vez disso, basta escrever uma função ou macro.
Se você usa muito essas construções ou deseja mais recursos, sugiro usar C ++. Com o C ++, você pode fazer algo semelhante a isso e ter código portátil.
fonte