Я пытаюсь обработать некоторый код, чтобы поймать и напечатать ошибку Сообщения. В настоящее время я использую макрос как-то так:
#define my_function(x) \
switch(function(x)) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
}
Обычно я никогда не записываю выходные данные функции, и это прекрасно работает. Но я' Мы нашли пару случаев, когда мне также нужно возвращаемое значение функции function ()
. Я попробовал что-то вроде следующего, но это приводит к синтаксической ошибке.
#define my_function(x) \
do { \
int __err = function(x); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
__err; \
} while(0)
Я мог бы объявить глобальную переменную для хранения возвращаемого значения функции, но это выглядит ужасно, и моя программа многопоточная, так что это может вызвать проблемы. Я надеюсь, что есть лучшее решение.
Это относительно сложный код, нет особых причин использовать его в макросе. Сделайте его встроенным
(C99) или статическим
(C89) или обоими, если вы действительно хотите поместить его в файл заголовка. Тогда с любым разумным компилятором это должно дать такую же эффективность, как и макрос.
GCC имеет функцию, называемую выражениями операторов
, поэтому, если определить макрос, как
#define FOO(A) ({int retval; retval = do_something(A); retval;})
, вы сможете использовать его как
foo = FOO(bar);
Извините, это правка...
Например, так:
#define my_function(x, out) \
{ \
int __err = function(x); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
__err; \
(*(out)) = _err; \
}
Чтобы сохранить парадигму pass-by-reference C, вы должны вызывать my_function так:
int output_err;
my_function(num, &output_err);
Таким образом, позже, если вы решите сделать my_function настоящей функцией, вам не нужно будет менять ссылки вызова.
Кстати, qrdl's "Statement Expressions" также является хорошим способом сделать это.