2017-01-10 9 views
0

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

int func1(int arg) { 
    prepare(); 
    doStuff(); 
    undo(); 
    return stuff; 
} 
char func2(int arg1, char* arg2) { 
    prepare(); 
    doOtherStuff(); 
    undo(); 
    return results; 
} 

Я слышал препроцессор довольно мощные, так что можно вставить prepare() и undo() функций до и после фактического тела функции, используя некоторый препроцессор фетиш? Я знаю, что настоятельно рекомендуется не использовать препроцессор, если его можно избежать, но мне все же интересно, возможно ли это.

Cheers.

ответ

1

Там вы идете:

#define MY_MACRO(doStuff) \ 
{       \ 
    prepare();   \ 
    doStuff    \ 
    undo();    \ 
} 
+0

Я собираюсь удалить этот ответ, как только вы его прочтете, потому что я не считаю его очень волюемым. –

+0

Спасибо. Тогда я пойду вперед и удалю сообщение. – Freeman

+0

Вы убедились, что он работает на вас? Аргумент 'doStuff', конечно, не является именем функции, но любой фрагмент кода, который вы хотите выполнить. –

1

Просто для записи, альтернативой было бы установить некоторую форму функции системы шаблона указателя:

typedef void stuff_t (void*); 

void execute (stuff_t* stuff, void* result) 
{ 
    prepare(); 
    stuff(result); 
    undo(); 
} 

int func1(int arg) { 
    int result; 
    execute(do_stuff, &result); 
    return result; 
} 

char func2(int arg1, char* arg2) { 
    char result; 
    execute(doOtherStuff, &result); 
    return result; 
} 

ли это хорошая идея или нет зависит от того, что на самом деле должен делать код и какие требования существуют при повторном использовании кода.

+0

Кто-то проголосовал за мой ответ без комментариев. Вы видите что-то не так? Благодарю. –

+0

@barakmanos Я полагаю, это зависит от того, что такое «doStuff». Это должно быть то, что может быть оценено на токере перед процессором. И, возможно, отсутствующая полуколока? 'MY_MACRO (a = b);' не будет компилироваться, но 'MY_MACRO (a = b;);' будет. – Lundin

+0

Ну, аргумент 'doStuff' - это любой фрагмент кода, который вы хотите выполнить (это также упоминается в комментарии к OP). Например, 'a = b; с = д; '. Таким образом, вы не ограничены одним заявлением. Конечно, я мог бы добавить, что полу-двоеточие на всякий случай, но я чувствовал, что здесь не будет смысла, потому что «любая часть кода», очевидно, означает «любой ** юридический ** код». Поэтому я не понимаю, почему это может быть хорошим предлогом для голосования. –