В этом коде я пытаюсь вернуть функцию, которая может добавлять ctx.a
к переданному аргументу x
.
Предполагаемый ответ — 4, но при запуске этого кода он печатает 6.
Что здесь не так?
Я попробовал этот код:
#include <stdio.h>
typedef struct {
int a;
} ctx_t;
typedef void(*with_ctx)(int);
with_ctx create_handler(ctx_t ctx) {
void handler(int x) {
printf("%d\n", ctx.a + x);
}
return handler;
}
int main() {
ctx_t ctx = { .a = 1 };
with_ctx handler = create_handler(ctx);
handler(3);
return 0;
}
То, что вы написали, недействительно. В частности, возврат handler
недействителен, поскольку после возврата create_handler()
handler
становится недействительным. Более того, определение функций внутри функций не является стандартом C, это расширение, которое поддерживается основными компиляторами, но определенно не рекомендуется и ведет себя не так, как вы ожидаете. В C нет встроенной функции, позволяющей реализовать такое каррирование, то есть то, что вы бы назвали «замыканием» в других языках.
Привет stackoverflow.com/questions/1023261/… вы пробовали функцию поиска?
Объявление функций внутри функций не поддерживается в C. Что происходит, так это то, что вы используете компилятор, который поддерживает это как расширение поверх C. Я думаю, что это поддерживает только gcc.
Что здесь не так?
Затем происходит следующее: переменная ctx
перестает существовать после return handler;
. Область видимости переменной ctx
внутри create_handler
перестает существовать после завершения функции на }
. Таким образом, вызов handler()
получит доступ к некоторой неопределенной области памяти, где раньше был ctx
. Его больше нет.
На языке программирования C невозможно создавать лямбды. См. Есть ли способ сделать каррирование на C? .
этот код на самом деле является тестовым кодом, я действительно хочу использовать nftw(), и указатель функции должен быть передан в nftw в качестве аргумента. но проблема начинается, когда мне приходится использовать базу данных, в которой я храню путь к каждому файлу в каталоге. если я добавлю параметр для предоставления контекста БД в функцию (тот, который будет передан в качестве аргумента), его подпись изменится и ее нельзя будет использовать в nftw, поэтому я подумал, почему бы не использовать функцию, в которой я могу определить БД и определить функцию в он использует указанную базу данных ctx и возвращает функцию для nftw().
Вы задали вопрос, получили ответ. Подумайте о том, чтобы опубликовать еще один вопрос, конкретно о nftw и проблеме, с которой вы столкнулись. Я не знаю, что такое nftw и над какой библиотекой или своим кодом вы работаете.
Если вы спрашиваете о nftw из posix pubs.opengroup.org/onlinepubs/009696699/functions/nftw.html, то эта функция не является реентерабельной и не потокобезопасной. Используйте глобальную переменную для контекста или напишите свой собственный nftw.
Стандарт C не допускает вложенных функций. Если ваш компилятор их допускает, вам нужно найти его документацию и разобраться в их семантике. Я предполагаю, что они не создают замыканий, поэтому попытка каррирования с их помощью не сработает.