2017-02-01 5 views
0

Я пытаюсь написать макрос отладки в общем подмножестве C и C++. Это то, что я придумал до сих пор:Расширение переменной строки в отладочном макросе

#define OUTPUT_ERROR(...) printf("%s(%d) : %s() : %s\n", __FILE__, __LINE__, __func__, #__VA_ARGS__) 

К сожалению, я не могу понять, как дать ему переменные для вывода. Есть ли способ принудительно расширить переменную во время выполнения? Например:

OUTPUT_ERROR("%s was broken", my_var); 

или просто на месте

OUTPUT_ERROR(my_var + "some text"); 
+3

избежать обучения точка с запятой в вашем макроопределение. –

+0

'printf' не рекурсивно форматирует строки – StoryTeller

+3

Макросы и' printf' имеют тенденцию быть очень C-ориентированными и меньше C++. Попробуйте воздержаться от добавления языковых тегов, которые вы фактически не используете. Если вы программируете на C, не добавляйте C++, даже если решение или код можно использовать в C++. –

ответ

0

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

Для достижения этой цели, вы можете использовать следующий макрос:

#define LOG(format, ...) \ 
printf("%s(%d) : %s() " format, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) 

Этот путь LOG("%d", 123) будет расширяться до printf("%s(%d) : %s() " "%s", __FILE__, __LINE__, __FUNCTION__, 123). Поскольку последовательные строковые литералы объединены ("a" "b" эквивалентно "ab"), формат printf правильно построен.

Также обратите внимание на использование , ## __VA_ARGS__. Это расширение GNU (см. https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html), которое допускает пустые переменные аргументы.

Этот метод, однако, не будет выполнен, если format не является строковым литералом. См. Пример: http://ideone.com/gMnaES

+0

Спасибо! Это именно то, что я искал. – scx

+0

Добро пожаловать! –

1

Мне кажется, что вы пытаетесь втиснуть слишком много в один звонок printf(). Вам не нужно это делать. В частности, для поддержки использования таких, как ваш первый пример:

OUTPUT_ERROR("%s was broken", my_var); 

можно легко разделить выход в течение нескольких printf() вызовов с помощью макроса, как это:

#define OUTPUT_ERROR(...) do { \ 
    printf("%s(%d) : %s() : ", __FILE__, __LINE__, __func__); \ 
    printf(__VA_ARGS__); \ 
    putchar('\n'); \ 
} while (0)