У меня есть следующая вспомогательная функция:
inline void DebugMessage(const TCHAR* fmtstr, ...)
{
va_list args;
va_start(args, fmtstr);
TCHAR buffer[256];
StringCbVPrintf(buffer, 256, fmtstr, args);
OutputDebugString(buffer);
va_end(args);
}
И я называю это дважды так:
DebugMessage(_T("Test %d\n", 1)); // incorrectly closed _T()
DebugMessage(_T("Test %d\n"), 1); // correctly closed _T()
Я получаю следующий вывод:
Test 0
Test 1
Второй случай работает как положено. Я запутался, почему первый случай вообще функционирует, а не является ошибкой?
_T
это не функция, это макрос, который (в сборке Unicode) расширяется до L ## x
, Смещенная скобка не вызывает ошибку компиляции, она просто изменяет, какие части строки используются макросом.
Макрос принимает только один параметр (x
) и так в первом случае при неправильном закрытии второй параметр (1
) просто отбрасывается, а число, которое вы получаете в выводе, является просто результатом случайных данных в стеке.
Обратите внимание, что по умолчанию VS 2012 выдаст предупреждение C4002 об этом (слишком много фактических параметров для макроса) поэтому вы можете проверить, правильно ли включены предупреждения.
Других решений пока нет …