I'm using easyloggingpp in a "big" cross platform project. Big enough that I can't create a simple running example that reproduce the behavior I'm about to describe.
So I have some enum
type define in some header, let say:
In types.h
:
typedef enum MyEnum
{
First,
Second
} MyEnum;
The enum is a
C
enum since the project is ABI safe and the API is a thin layer of C functions and types (Our implementation for the Hour Glass pattern)
and it also has 2 functions to handle printing, assume that these are the functions (in reality only the functions' bodies are different):
inline std::ostream & operator << (std::ostream & out, MyEnum value)
{
return out << get_string(value);
}
In types.cpp
, I have:
namespace MyNamespace
{
const char* get_string(MyEnum value)
{
assert(0);
}
}
If I call something like this in my code
MyEnum x = First;
std::stringstream os;
os << "Value of x is: " << x;
The assert(0)
I have in the get_string()
function will be triggered.
But if I call the logger:
LOG_INFO("Value of x is: " << x);
For some reason, In Visual Studio (2017 if that matters), when the logger's inner stream member (which is also of type std::stringstream
) is called with x
it calls the <ostream>
function: _Myt& __CLR_OR_THIS_CALL operator<<(int _Val)
, i.e. it treats the enum to an integer, and prints the value as a number instead of using my operator overload.
But, in Linux - the same code, compiled with gcc 5.4.0
, calls my operator<<
and does trigger the assertion.
I'm not really sure where to start in order to understand this...
So the real question is - what could cause such a difference between compilers\OSs? and where do I start with debugging it? or if someone knows what is causing this, I'd love to know.
EDIT:
LOG_INFO
is a macro of the logging infrastructure which eventually calls:
m_logger->stream() << msg;
where m_logger->stream()
returns std::stringstream&
and msg
is a templated value parameter which in my example is the instance of x