Проблема
Есть набор макросов:
Ещё в Visual Studio 2005 появилась поддержка макросов с переменным количеством аргументов. Благодаря этому, макросы можно переписать таким образом, чтобы функция DbgPrint вызывалась только один раз, тем самым гарантируя консистентность отображения отладочной информации:
Updated 17.04.2011
Для большей наглядности добавлены примеры использования.
Есть набор макросов:
#define DBGPRINT(Level, Prefix, Fmt) \
{ \
if ((Level) >= gDbgLevel) \
{ \
DbgPrint(DBGPRINT_PREFIX": %s", Prefix); \
DbgPrint Fmt; \
} \
}
#define TERSE_FN(Fmt) DBGPRINT(DBG_LEVEL_TERSE, __FUNCTION__"(): ", Fmt)
Данные макросы позволяют выводить отладочную информацию в формате:MyPrefix: FunctionName(): FormattedMessageНа первый взгляд всё нормально. Но если TERSE_FN вызывается из двух потоков:
Thread 1: TERSE_FN(("Important message with status: %x\n", status));
Thread 2: TERSE_FN(("Another important message with status: %x\n", status));
вывод может быть неконсистентным из за асинхронного использования DbgPrint:MyPrefix: MyPrefix: Function2(): Another important message with status: 00000000 Function1(): Important message with status: 00000000Решение
Ещё в Visual Studio 2005 появилась поддержка макросов с переменным количеством аргументов. Благодаря этому, макросы можно переписать таким образом, чтобы функция DbgPrint вызывалась только один раз, тем самым гарантируя консистентность отображения отладочной информации:
#define TERSE_FN(Fmt, ...) \
{ \
if (gDbgLevel <= DBG_LEVEL_TERSE) \
DbgPrint(DBGPRINT_PREFIX ": " __FUNCTION__"(): " Fmt, __VA_ARGS__); \
}
Примеры использования:TERSE_FN("Important message with status: %x\n", status);
TERSE_FN("Request completed: Object %p, Status %x\n", someObject, status);
Следует обратить внимание что исчезли дополнительные круглые скобки, и теперь вызов макроса похож на вызов ф-ции.Updated 17.04.2011
Для большей наглядности добавлены примеры использования.
Комментариев нет:
Отправить комментарий