я использую easyloggingpp в «большом» кроссплатформенном проекте. Достаточно большой, чтобы я не смог создать простой бегущий пример, воспроизводящий поведение, которое я собираюсь описать.
Итак, у меня есть некоторые enum
Тип определить в некотором заголовке, скажем:
В types.h
:
typedef enum MyEnum
{
First,
Second
} MyEnum;
Перечисление является
C
enum, так как проект безопасен для ABI, а API представляет собой тонкий слой функций и типов C (наша реализация для шаблона Hour Glass)
и он также имеет 2 функции для обработки печати, предположим, что это функции (на самом деле отличаются только тела функций):
inline std::ostream & operator << (std::ostream & out, MyEnum value)
{
return out << get_string(value);
}
В types.cpp
, Я имею:
namespace MyNamespace
{
const char* get_string(MyEnum value)
{
assert(0);
}
}
Если я называю что-то подобное в моем коде
MyEnum x = First;
std::stringstream os;
os << "Value of x is: " << x;
assert(0)
У меня в get_string()
функция будет запущена.
Но если я позвоню регистратору:
LOG_INFO("Value of x is: " << x);
По какой-то причине, в Visual Studio (2017, если это имеет значение), когда внутренний элемент потока регистратора (который также имеет тип std::stringstream
) называется с x
это вызывает <ostream>
функция: _Myt& __CLR_OR_THIS_CALL operator<<(int _Val)
то есть он обрабатывает перечисление как целое число и печатает значение как число вместо использования перегрузки моего оператора.
Но в Linux — тот же код, скомпилированный с gcc 5.4.0
зовет мой operator<<
и действительно вызывает утверждение.
Я не совсем уверен, с чего начать, чтобы понять это …
Таким образом, реальный вопрос — что может вызвать такую разницу между компиляторами \ ОС? и с чего начать с его отладки? или если кто-то знает, что является причиной этого, я хотел бы знать.
РЕДАКТИРОВАТЬ:
LOG_INFO
это макрос инфраструктуры логирования, который в конечном итоге вызывает:
m_logger->stream() << msg;
где m_logger->stream()
возвращается std::stringstream&
а также msg
является параметром шаблонного значения, который в моем примере является экземпляром x
Задача ещё не решена.
Других решений пока нет …