LINUX.ORG.RU

Задача для извращенцев (или гениев) в си

 


1

1

Дано:

Библиотека

Есть функция a, внутренняя, снаружи недоступна:

a(int, int, structtype1, int)
{
   КОД1
   Вызов функции aa, принимающей параметр structtype1
   КОД2
}
И есть функция b, внутренняя, снаружи недоступна:
b(int, int, structtype2, int)
{
   КОД1
   Вызов функции bb, принимающей параметр structtype2
   КОД2
}

За исключением вызова разных функций (aa и bb), функции полностью идентичны. Вызовы внутри неоднократные.

Теперь есть функция c1(), внешняя, вызывается пользователем:

c1(structtype1 st1)
{
    КОД3
    a(..., st1, ...)
    КОД4
}
и функция c2(), тоже внешняя, вызывается пользователем:
c2(structtype2 st2)
{
    КОД5
    b(..., st2, ...)
    КОД6
}

Чего хочется:

Функции a и b полностью идентичны, за исключением того что они вызывают разные функции внутри. Хочу слить их в одну, потому что
1) Функции дорабатываются и проблематично держать код обоих синхронизированным.
2) Вообще держать две копии одного кода в проекте как-то не комильфо.

Какие мысли есть? Есть мысль намутить что-нибудь с указателями на функции, но там разный тип параметров...

★★

Последнее исправление: cetjs2 (всего исправлений: 1)

Лапшу во все поля ab(int, int, structtype1, structtype2, int). А вообще, union отменили чтоль?

Tark ★★
()

void ab(int, int, void *, void (*)(void *), int);

nanoolinux ★★★★
()

КОД_1_2(int , int , void * ,int, flag);

abs ★★★
()
Ответ на: комментарий от sambist

Ну и да, лучше структуры объединить в одну с юнионом, тем более что они вроде как логически связаны, судя по вопросу.

Deleted
()

Если union то либо tagged, либо нужен дополнительный параметр, поскольку иначе не понятно вызывать aa или bb.

А вообще, самое же очевидное - оформить в отдельные функции КОД1 и КОД2. Для извращенцев - в макросы.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

А вообще, самое же очевидное - оформить в отдельные функции КОД1 и КОД2

В примере я упростил, там на самом деле что-то такое:

a(...)
{
   КОД1
   if (...)
   {
    while (...)
      aa(...)
    КОД 2
    aa(...)
   }
   КОД 3
   if (...)
     aa(...)
   else
     aa(...)
}
В общем оно никак там не разбивается.

Да, можно макросы задействовать, но оно тогда неотлаживаемым будет.

sambist ★★
() автор топика

делаешь функцию-алиас (aabb ?), которая в зависимости от параметра вызывает aa или bb, сливаешь код a и b , в нем по условии вызываешь aabb ...

anTaRes ★★★★
()

Для такого придумали callback.

c1(int whatever, void *arg, void (*f)(void *arg))
{
     codex;
     f(arg);
     codey;
}

А ещё, что бы скрыть, можно обернуть c1 и с2 wrapper'ами.

beastie ★★★★★
()

Шаблоны на дефайнах.

#define TYPE structtype2 
#define NAME c2
#include "c1_c2_template.h"

#define TYPE structtype1
#define NAME c1
#include "c1_c2_template.h"
intelfx ★★★★★
()
Ответ на: комментарий от beastie

+1 за колбэк, самое нормальное решение похоже.

Kiborg ★★★
()

как то так

typedef void (*aa_or_bb)(void *);

void aa(struct type1 *st1) { ... }
void bb(struct type2 *st2) { ... }

void ab(int, int, aa_or_bb callback, void *st, int)
{
    КОД1
    callback(st);
    КОД2
}

void c1(struct type1 *st1)
{
    КОД3
    ab(..., (aa_or_bb) &aa, st1, ...)
    КОД4
}

c2(struct type2 *st2)
{
    КОД5
    ab(..., (aa_or_bb) &bb, st2, ...)
    КОД6
}

Legioner ★★★★★
()
Ответ на: комментарий от intelfx

Нет, этого на эту скользкую дорожку вставать не стоит.

AptGet ★★★
()
Ответ на: комментарий от intelfx

По-моему, если нужен Си++, то стоит использовать Си++. Ну, за исключением случая с embedded, где под девайс может быть только один (корявый) компилятор, который не умеет Си++. Но это надо ещё подумать, где там пригодятся шаблоны вообще.

ilammy ★★★
()
Ответ на: комментарий от x4DA

Смысл был в том, что не надо придумывать костыль, чтоб код на С выглядел как код на С++. Если хочешь, чтоб код выглядел как код на С++, то имеет смысл использовать для этого С++.

А вот после вопроса «как понять, что тебе нужен С++» возможно имеет смысл запасаться попкорном😊

bogus_result
()
Ответ на: комментарий от bogus_result

Если хочешь, чтоб код выглядел как код на С++

хочешь

как код на C++

...

Kuzy ★★★
()
Ответ на: комментарий от intelfx

Честно говоря, я не считаю плановые шаблоны образцом читаемости. И уж точно колбэк является более удачным решением. Кроме того, подключение кода функции из другого файла путем include сбивает с толку, это плохой код. В общем, можно, конечно, и так, и оно будет работать, но это неудачный вариант.

Kiborg ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.