我在"大"中使用easyloggingpp跨平台项目。足够大,我无法创建一个简单的运行示例,重现我即将描述的行为。
所以我在某个标题中有一些enum
类型定义,比如说:
在types.h
:
typedef enum MyEnum
{
First,
Second
} MyEnum;
枚举是一个
C
枚举,因为该项目是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
的实例