У меня есть следующий макрос в моей библиотеке журналирования:
#define TRACE_E(__logCat,__format,...) \
do { \
::dbg::LogCategory * const __catPtrVal = (::dbg::LogCategory *)(__logCat); \
if( NULL != __catPtrVal && __catPtrVal->IsEnabled() ) \
{ \
__catPtrVal->Error( __format, __VA_ARGS__ ); \
} \
} while( false )
Под Visual Studio (2008) он работает как задумано, то есть я могу сделать оба TRACE_E( pLog, "some message without parameters" );
а также TRACE_E( pLog, "some message with parameters %d %d", 4, 8 );
Но при использовании этой же библиотеки с eclipse и Android NDK я получаю ошибку компиляции, если не передаю хотя бы один параметр после строки формата в моем макросе, т.е. TRACE_E( pLog, "some message without parameters" );
не действует, но TRACE_E( pLog, "some message without parameters", 0 );
есть, что заставляет меня передавать фиктивный параметр, когда ничего не нужно.
Есть ли разница в поведении с помощью макроса с переменным аргументом при использовании g ++, а не компилятора Visual Studio? Спасибо.
Да. То, что вы пытаетесь сделать, невозможно в стандарте C или C ++.
Это, возможно, дефект в соответствующих стандартах, для которых разные компиляторы имеют разные обходные пути. Visual Studio пытается заставить его работать как есть, gcc и clang требуют следующего синтаксиса:
__catPtrVal->Error( __format, ##__VA_ARGS__ );
Это описано Вот для gcc; Clang только что принял GCC способ делать вещи. К сожалению, MSVC не понимает этот синтаксис. Насколько мне известно, в общем случае не существует переносимого способа решения этой проблемы.
Для вашего конкретного макроса, однако, вы могли бы просто написать
#define TRACE_E(__logCat,...) \
do { \
::dbg::LogCategory * const __catPtrVal = (::dbg::LogCategory *)(__logCat); \
if( NULL != __catPtrVal && __catPtrVal->IsEnabled() ) \
{ \
__catPtrVal->Error(__VA_ARGS__ ); \
} \
} while( false )
Так как единственное место, где вы используете __format
прямо перед __VA_ARGS__
,
Примечание: вы используете много зарезервированные идентификаторы там. Если вы не пишете стандартную библиотечную реализацию, вам следует немного упростить подчеркивание.