2013-04-26 3 views
3
gcc (GCC) 4.7.2 
c89 

Можно ли вызывать переменный макрос?Можно ли выровнять переменный макрос?

У меня есть следующий макрос, и я хочу вывести полученную строку из fmt и аргументов.

#define ERROR_MESSAGE(priority, fmt, ...)  \ 
    do {           \ 
     MODULE_LOG(priority, fmt, ##__VA_ARGS__);\ 
} while(0) 

Итак, я просто хочу, чтобы получить полную строку в fmt и ##__VA_ARGS__, так что я могу назначить его char * выполнить некоторые дополнительные операции на нем.

+1

Двойной хэш - это оператор конкатенации, а не оператор stringify, который является единственным хешем. –

+2

Матрицы Variadic были введены в C99 –

+1

@JoachimPileborg: использование '##' является расширением GCC, которое стирает запятую перед '##', если список '__VA_ARGS__' пуст. Есть вопрос о том, что где-то на SO; Я встретил нотацию в ответ, который я недавно перечитывал. (Один x-ref - [Определение макроса] (http://stackoverflow.com/questions/7788850/macro-definition/7788888#7788888); лучший вариант - [C#define macro для отладки печати] (http: // stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing/1644898#1644898).) –

ответ

6

Um, no. Предварительная обработка происходит до компиляции кода. Он существует в совершенно другой вселенной из исполняющей программы. Одна вещь, которую вы можете сделать, выполняется только на этапе предварительной обработки и проверяет выход (для печати вывода препроцессора используйте gcc-переключатель -E).

О том, что вы можете сделать, это перенаправить это в файл, а затем прочитать файл в программе.


Дальше подумайте, позвольте мне отступить от «нет» и изменить его на «возможно». Взгляните на this other answer of mine, который реализует макрос «foreach» для переменных массивов.

Таким образом, используя APPLYXn (и, неявно, PPNARG), вы могли бы применить STR(x) #x макрос на аргументах, как это (нб, как написано, APPLYXn может обрабатывать до 15 аргументов):

#define X(x) #x 
#define ERROR_MESSAGE(priority, fmt, ...)  \ 
    "do {MODULE_LOG(" X(priority) X(fmt) APPLYXn(__VA_ARGS__) ");} while(0)" 

int main() { 
    printf("%s\n", ERROR_MESSAGE(3, "%d", 5)); 
    return 0; 
} 

gcc -E производит

# 1 "strvar.c" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "strvar.c" 
# 71 "strvar.c" 

int main() { 
    printf("%s\n", "do {MODULE_LOG(" "3" "\"%d\"" "5" ");} while(0)"); 
    return 0; 
} 

И компилятор объединит все эти строковые литералы в одну строку.

Смежные вопросы