Использование и возврат выходных данных в макросе C

Я пытаюсь обработать некоторый код, чтобы поймать и напечатать ошибку Сообщения. В настоящее время я использую макрос как-то так:

#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)

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

13
задан A-Sharabiani 14 December 2017 в 01:17
поделиться

3 ответа

Это относительно сложный код, нет особых причин использовать его в макросе. Сделайте его встроенным (C99) или статическим (C89) или обоими, если вы действительно хотите поместить его в файл заголовка. Тогда с любым разумным компилятором это должно дать такую ​​же эффективность, как и макрос.

10
ответ дан 1 December 2019 в 17:15
поделиться

GCC имеет функцию, называемую выражениями операторов

, поэтому, если определить макрос, как

#define FOO(A) ({int retval; retval = do_something(A); retval;})

, вы сможете использовать его как

foo = FOO(bar);
56
ответ дан 1 December 2019 в 17:15
поделиться

Извините, это правка...

  1. Я думаю, вам нужны только фигурные скобки. Ключевые слова do...while не нужны
  2. Убедитесь, что обратные косые черты являются последними символами в каждой строке (без пробела после).
  3. Если вам нужно получить значение err из макроса, вы можете просто добавить параметр

Например, так:

 #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" также является хорошим способом сделать это.

2
ответ дан 1 December 2019 в 17:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: