Как структурировать буфер символов для макроса C - PullRequest
0 голосов
/ 24 января 2019

У меня есть макрос LOG(fmt, ...), который не работает при использовании char buf[] в качестве fmt.

Приведенный ниже код является полным (на самом деле) рабочим примером кода. В some_function() я пытаюсь использовать LOG() двумя различными способами, но работает только первый подход.

Чтобы решить эту проблему, я попытался использовать #define LOG_STR(x) #x следующим образом:

  1. К stringify что получено в #define LOG путем применения LOG_STR() к format следующим образом: LOG_STR(format); и

  2. Чтобы применить LOG_STR() непосредственно к печати следующим образом: LOG(LOG_STR(fmt), 6).

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

    #include <stdio.h>

    #define LOG(format, ...) do {                             \
                fprintf(stderr, "[LOG] " format " [%s]\n",    \
                        ##__VA_ARGS__, __func__);             \
            } while (0)

    static void some_function()
    {
        // This works
        LOG("This is a number: %d", 5);

        // This does not work
        const char fmt[] = "This is a number: %d";
        LOG(fmt, 6);
    }

    int main(void)
    {
        some_function();
        return 0;
    }

Когда я компилирую код выше, я получаю следующую ошибку:

$ gcc -o log-macro-str log-macro-str.c
log-macro-str.c: In function ‘some_function’:
log-macro-str.c:15:6: error: expected ‘)’ before ‘fmt’
  LOG(fmt, 6);
      ^
log-macro-str.c:4:29: note: in definition of macro ‘LOG’
    fprintf(stderr, "[LOG] " format " [%s]\n",    \
                             ^~~~~~

Я бы хотел использовать LOG() обоими способами, как в some_function() или без модификаторов, и просто печатать строку. Я подозреваю, что мне, возможно, придется привести в порядок часть format, но я не могу сделать это правильно.

Что я делаю не так и как я могу решить эту проблему?

1 Ответ

0 голосов
/ 24 января 2019

Оператор stringify, # в макросе, преобразует токены препроцессора в текст в строковом литерале.Он не изменит содержимое буфера char на строковый литерал времени компиляции.

Чтобы ваш макрос работал, используйте несколько операторов fprintf:

#define LOG(format, ...) do {                          \
            fprintf(stderr, "[LOG] ");                 \
            fprintf(stderr, format, __VA_ARGS__);      \
            fprintf(stderr, " [%s]\n", __func__);      \
        } while (0)
...