У меня есть эта система регистрации, для которой я ищу ярлык для некоторых манипуляций со строками.
Система ведения журнала используется с помощью функциональных макросов, которые затем перенаправляют на один вызов функции. Например. #define Warning(...) LogMessage(eWarning, __VA_ARGS__);
.
LogMessage затем делает snprintf
в новый буфер и затем представляет это сообщение любым установленным целям журнала; printf, OutputDebugString и т. д.
К сожалению, я столкнулся с проблемой, когда имеющийся у нас буфер недостаточно велик, поэтому выходные данные усекаются. Я также понял, что этот метод потерпит неудачу, если в выходном сообщении есть символы процента, поскольку snprintf попытается обработать va_args. Наконец, поскольку большинство наших сообщений журнала не используют va_args, глупо копировать строку просто для того, чтобы представить ее регистраторам.
Итак, учитывая мой прототип функции, могу ли я перегружаться в зависимости от наличия эллипсов? Другими словами, должен ли я предположить, что я могу сделать что-то вроде:
LogMessage(LogLevel, const char* message, ...);
LogMessage(LogLevel, const char* message);
Мои попытки Google не дали ничего особенно полезного (просто показывал мне, что эллипсы будут совпадать, если ничего не происходит, в отличие от моих требований, которые ничто соответствует), и мой первоначальный удар по реализации только что дал мне неоднозначная ошибка вызова функции.
С ошибкой я должен просто признать, что я не могу этого сделать, но мне интересно, просто ли я использую компилятор или, может быть, я делаю это неправильно. Я могу добиться аналогичного эффекта с
// edited version of what I really have to remove our local APIs,
// please excuse minor errors
const char* message = NULL;
char buffer[512];
va_list args;
va_start(args, format);
if(strcmp(format, "%s") == 0) {
message = va_arg(args, const char*);
}
else if (strchr(format, '%') == NULL) {
message = format;
}
else {
vsnprintf(buffer, 512, format, args);
message = buffer;
}
va_end(args);
... но это кажется расточительным в типичном случае, который можно узнать просто по количеству передаваемых параметров. Например. если эллипсы ничего не соответствуют, выберите другую функцию? Если это не работает, есть ли другой способ, который я могу попробовать, который не требует, чтобы пользователь определился с именем макроса, какая функция будет вызвана? Честно говоря, это не так уж и много об «растрате», когда я понял, что если кто-то случайно сказал Error("Buffer not 100% full");
в своем сообщении журнала и в результате получил «Buffer not 1007.732873e10ull».
Редактировать: Хотя на мой пример ответили "не делай этого", можно ли ответить на сам вопрос?