Как сделать каррирование в C

В этом коде я пытаюсь вернуть функцию, которая может добавлять 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;
}

Стандарт C не допускает вложенных функций. Если ваш компилятор их допускает, вам нужно найти его документацию и разобраться в их семантике. Я предполагаю, что они не создают замыканий, поэтому попытка каррирования с их помощью не сработает.

n. m. could be an AI 22.06.2024 23:33

То, что вы написали, недействительно. В частности, возврат handler недействителен, поскольку после возврата create_handler()handler становится недействительным. Более того, определение функций внутри функций не является стандартом C, это расширение, которое поддерживается основными компиляторами, но определенно не рекомендуется и ведет себя не так, как вы ожидаете. В C нет встроенной функции, позволяющей реализовать такое каррирование, то есть то, что вы бы назвали «замыканием» в других языках.

Marco Bonelli 22.06.2024 23:34

Привет stackoverflow.com/questions/1023261/… вы пробовали функцию поиска?

KamilCuk 23.06.2024 00:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
100
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Объявление функций внутри функций не поддерживается в C. Что происходит, так это то, что вы используете компилятор, который поддерживает это как расширение поверх C. Я думаю, что это поддерживает только gcc.

Что здесь не так?

Затем происходит следующее: переменная ctx перестает существовать после return handler;. Область видимости переменной ctx внутри create_handler перестает существовать после завершения функции на }. Таким образом, вызов handler() получит доступ к некоторой неопределенной области памяти, где раньше был ctx. Его больше нет.

На языке программирования C невозможно создавать лямбды. См. Есть ли способ сделать каррирование на C? .

этот код на самом деле является тестовым кодом, я действительно хочу использовать nftw(), и указатель функции должен быть передан в nftw в качестве аргумента. но проблема начинается, когда мне приходится использовать базу данных, в которой я храню путь к каждому файлу в каталоге. если я добавлю параметр для предоставления контекста БД в функцию (тот, который будет передан в качестве аргумента), его подпись изменится и ее нельзя будет использовать в nftw, поэтому я подумал, почему бы не использовать функцию, в которой я могу определить БД и определить функцию в он использует указанную базу данных ctx и возвращает функцию для nftw().

neo 23.06.2024 06:36

Вы задали вопрос, получили ответ. Подумайте о том, чтобы опубликовать еще один вопрос, конкретно о nftw и проблеме, с которой вы столкнулись. Я не знаю, что такое nftw и над какой библиотекой или своим кодом вы работаете.

KamilCuk 23.06.2024 10:51

Если вы спрашиваете о nftw из posix pubs.opengroup.org/onlinepubs/009696699/functions/nftw.html, то эта функция не является реентерабельной и не потокобезопасной. Используйте глобальную переменную для контекста или напишите свой собственный nftw.

KamilCuk 23.06.2024 10:56

Другие вопросы по теме