Я нашел этот кусок кода на GitHub, но не совсем понял:
#define lambda(ret_type, _body) ({ ret_type _ _body _; })
Затем:
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
Что делают подчеркивания внутри #define
и как он возвращает указатель на функцию?
gcc -E
), чтобы увидеть, что он делает?Ответы:
Используя этот макрос,
расширяется до:
В фигурных скобках при этом используются вложенные функции GCC для создания функции, выполняющей нужную операцию. Во внутренней области у этого есть имя
_
.Затем, как отмечает interjay, используются выражения операторов GCC . По сути, функция
_
назначена указателюmax
.Если такой макрос не используется, его можно написать по-другому и использовать как:
В этом примере кода можно сравнить три метода .
источник
max(4, -30);
вместоapply_binary_op(max, 4, -30);
?Это называется выражением оператора и создает «лямбду» (или вложенную функцию ) и возвращает на нее указатель. Это GNU C-специфично.
Макрос расширяется до:
_
конце это какreturn
.Подчеркивание - это имя функции, которая создается и «возвращается». Он используется потому, что это редко используемый идентификатор (по уважительной причине;
_
вполне возможно, наименее описательный идентификатор из возможных).Причина, по которой выражение выражение используется так
_
, не будет определена после выхода из области выражения выражения.Итак, пройдемся по макросу:
ret_type
тип возврата "лямбда"._
это имя функции, используемой внутри него, потому что это необычное имя идентификатора._body
состоит из аргументов и тела функции. Трейлинг_
«возвращает» «лямбду».Этот код находится в Let's Destroy C (это подходящее имя). Вы не должны использовать это. Это заставит ваш код работать только на компиляторах, которые поддерживают расширения GNU C. Вместо этого просто напишите функцию или макрос.
Если вы часто используете подобные конструкции или хотите больше возможностей, я предлагаю использовать C ++. С C ++ вы можете сделать что-то похожее на это и иметь переносимый код.
источник