> Ты сам то проверял в какое говно эти твои лямбды компилируются? Даже
> при условии, что от С++ там будут только одни лямбды и
> ничего больше.Не, не проверял, но раз ты спросил проверил. Легенда такая: set_callback хочет функцию, которая принимает unsigned int, а наш real_callback принимает unsigned char. То есть требуется преобразование типов, которое даже не удастся оптимизировать в noop. Вот собственно код:
typedef int (*callback_t)(unsigned);
extern void set_callback(callback_t fn);
extern int real_callback(unsigned char);
void do_it()
{
set_callback([](auto a) { return real_callback(a); });
}
Компилируем в асм, и получаем... Я не буду копировать сюда вывод g++ -O2 -S -fverbose-asm, ты его сам можешь получишь, я упрощу его слегка для читаемости:
lambda:
movzbl %dil, %edi # tmp87, D.43746
jmp real_callback #
do_it:
leaq lambda(%rip), %rdi #,
jmp set_callback #
Какая из перечисленных строк содержит "гoвнo", о котором ты говоришь?
Тут лямбда, которая не полагается ни на какое окружение, ей не нужны malloc'и, это просто безымянная pure функция. При некотором везении преобразования типов это no-op, то есть возможна оптимизация вида не создавать никакой лямбды, и передать вместо неё указатель на функцию, которая вызывается из лямбды.
Вот когда лямбда, например, обращается к переменным из стекового фрейма функции, в которой она объявлена, вот тогда всё становится гораздо интереснее: можно сделать без malloc'а и жирных указателей, но придётся использовать заморочные техники выяснения адресов переменных на стеке, и при этом время жизни лямбды будет ограничено временем жизни стекового фрейма, на котором она объявлена. Альтернатива -- это malloc под environment лямбды и жирные указатели, которые будут объединять в себе указатель на код, указатель на окружение, причём последний ещё и какой-то техникой динамической сборки мусора прикрывать придётся (если речь о C++, то ref_count'ом), потому что это окружение должно существовать пока существует хотя бы один из жирных указателей на эту лямбду, и его надо подчистить, когда заканчивается время жизни последнего. Иначе будет либо утечка памяти, либо обращение к освобождённой памяти.
Но ежели ты идёшь на такие замороки, то ты же должен понимать, что ты делаешь?