2016-10-12 4 views
1

я эти макросы, которые генерируют ошибку в Visual Studio 2015.Запятая в C/C++ макрос передается другой макрос

#define log_params __FILE__, __LINE__ 
#define log(file, line, message, ...) _snprintf_s(nullptr, 0, 0, message, __VA_ARGS__) 

Теперь называют это никогда не работает

log(log_params, "testing %d", 4) 

Любые мысли? Я также проверил вывод препроцессора и это:

_snprintf_s(nullptr, 0, 0, 4); 

EDIT 1 Интересная найти

#define log(file, line, message, ...) file line 

будет производить это:

"service.cpp", 164 "testing %d" 

Это нормально?

+2

журнал макрос ожидает (по крайней мере) 4 аргумента. –

+0

Я получаю '_snprintf_s (nullptr, 0,0,4,);' что имеет смысл. Вы уверены, что вывод препроцессора был скопирован/вставлен правильно? – user3386109

+0

Это не C, а C++. – Olaf

ответ

1

Это решение m у проблемы

__VA_ARGS__ expansion using MSVC

так что теперь я использую

#define EXPAND(x) x 
#define Log_printf(file_name,line, message,...) _snprintf_s(nullptr, 0,0,message, __VA_ARGS__) 
#define Log(...) EXPAND (Log_printf(__VA_ARGS__)) 
3

Следующий вызов:

log(log_params, "testing %d", 4) 

вызовы функций, как макрос log с тремя фактических аргументов. Их замены не разрешаются до того, как аргументы передаются макросу. Другими словами, даже если log_params содержит запятую сама по себе, эта запятая не учитывается во время функционального разрешения макрособрания.

Таким образом, вы эффективно передавать аргументы как:

file ---> __FILE__, __LINE__ 
line ---> "testing %d" 
message ---> 4 

Первые два параметра игнорируются замены, и в конечном итоге вы получите:

_snprintf_s(nullptr, 0, 0, 4, __VA_ARGS__) 

, которые в свою очередь становятся (как MSVC счастлив для игнорирования требования по крайней мере для одного вариационного аргумента):

_snprintf_s(nullptr, 0, 0, 4)