I work on a logging mechanism using macros:
#define LOGFATAL 1 // very serious errors
#define TOSTRING(s) dynamic_cast< std::ostringstream & >((std::ostringstream() << s ) ).str()
#define LOG_TRANSFER(t, s) "[" << t << "] " << s
void inline print_log(const char *level, const std::string& value)
{
std::cout << "[" << timestamp() << "]["<< level << "]" << value << std::endl;
}
#ifdef DEBUGGING
#define DEBUG_OUT(l, s) print_log(l, TOSTRING(s));
#else
#define DEBUG_OUT(s, l)
#endif
#if DEBUGGING >= LOGFATAL
#define LOG_FATAL(s) DEBUG_OUT("FATAL", s)
#else
#define LOG_FATAL(s)
#endif
I use it his way:
LOG_TRACE(LOG_TRANSFER(ptr, “MemoryManager > allocate “))
LOG_TRACE(“MemoryManager > size : ” << active_list.size() )
What gcc does is:
print_log("TRACE", dynamic_cast< std::ostringstream & >((std::ostringstream() << "[" << ptr << "] " << "MemoryManager > allocate " ) ).str());
print_log("TRACE", dynamic_cast< std::ostringstream & >((std::ostringstream() << "MemoryManager > size : " << active_list.size() ) ).str());
This looks ok to me but I get the following output:
[0 s][TRACE]0x80940d40x9988ea8] MemoryManager > allocate
[0 s][TRACE]0x80941e01
Where is the mistake?
The problem is with this:
or more precisely with this:
The reason is that the expression
std::ostringstream()is a temporary object on which you cannot call non-member overload<<, as all non-member<<overloads take first argument asstd::ostream&, which is non-const reference. But a temporary cannot be bound to non-const reference. Hence, a member function is called when you want to printchar*, which gets converted intovoid*and address is printed.You need to do a little hack. Convert the temporary object (rvalue) into a reference type (lvalue) as:
Why would I call
flush()like that??Well you can call a member function on a temporary object. I chose
flush()because it returnsstd::ostream&which is non-const reference, and which is what we need.The difference it makes is this:
The first one calls the member
operator<<which prints the address, the second one call the non-memberoperator<<which prints the c-string. That is the difference behind the scene.So try this:
That should work.
Also, I would suggest
static_casthere, as you know the type already:It doesn’t depend on RTTI.