Leon
Leon

Reputation: 2055

How to bypass a << calling as if "#ifndef DEBUG" macro in c++?

I coded a little logging-lib for myself, and it accepts two forms calling.

The one likes a normal function calling, the other likes a std::ostream << operator output. And then I defined a few of Macros respectively for every log-levels as following:

#ifdef DEBUG
#define LOG_DEBUG( strLogBody )  appendLog( leon_log::LogLevel_e::ellDebug,  std::string( __func__ ) + "()," + ( strLogBody ) )
#define LOG_INFOR( strLogBody ) appendLog( leon_log::LogLevel_e::ellInfor,  std::string( __func__ ) + "()," + ( strLogBody ) )
#define log_debug ( Logger_t( LogLevel_e::ellDebug ) << __func__ << "()," )
#define log_infor ( Logger_t( LogLevel_e::ellInfor ) << __func__ << "()," )
//...more for other log-levels

#else

#define LOG_DEBUG( strLogBody )
#define LOG_INFOR( strLogBody ) appendLog( leon_log::LogLevel_e::ellInfor, ( strLogBody ) )
#define log_debug ( Logger_t( LogLevel_e::ellDebug ) )
#define log_infor ( Logger_t( LogLevel_e::ellInfor ) )
//...more for other log-levels
#endif

When there is a "DEBUG" macro defined in the client-code space, both forms product objective codes for DEBUGGING purpose. When there is no "DEBUG" macro defined, the former form(likes a function call) do not products any binary codes to speed up my app( as I want), while the latter form products codes anyway.

Is there a way, I can bypass those "<<" callings as same as doing with those normal function callings?

So far, I'm using a solution that similars to the one @Botje given. The difference just is that mines is a friend-func of the Logger_t, while Botje's is a member-func. Follows is mine:

template <typename T>
inline Logger_t& operator<<( Logger_t& lgr, const T& body ) {
   if ( lgr.m_LogLevel >= g_ellLogLevel )
      dynamic_cast<std::ostringstream&>( lgr ) << body;

   return lgr;
};

But I guess that GCC still products the function calling binary-codes, even though those are all of "no-op" calls. I don't know how to dis-assemble my target prog, so I can't confirm it.

Thanks! Pls forgive my ugly English!

Upvotes: 0

Views: 137

Answers (1)

Botje
Botje

Reputation: 30860

Why not make operator<< a no-op in non-debug builds:

#ifndef DEBUG
struct Logger_t {
  template <class T>
  Logger_t& operator <<(const T& o) { return *this; }
};
#endif

The compiler should be able to reduce an entire log_debug << ... << ... chain to nothing.

If you want to avoid function calls in the << chain as well, define operator bool for Logger_t and

#define log_debug false && Logger_t{}

Upvotes: 2

Related Questions