google / glog

C++ implementation of the Google logging module
http://google.github.io/glog/
BSD 3-Clause "New" or "Revised" License
7.05k stars 2.06k forks source link

Can we use google::NullStream instead of google::LogMessageVoidify in LOG_IF? #1119

Open folery opened 3 months ago

folery commented 3 months ago
#define LOG_IF(severity, condition) \
  static_cast<void>(0),             \
      !(condition)                  \
          ? (void)0                 \
          : google::logging::internal::LogMessageVoidify() & LOG(severity)

This is how LOG_IF is implemented now. After reading the doc https://github.com/asplingzhang/asplingzhang.github.io/blob/main/docs/_posts/webrtc/logging/2022-06-14-why-static_cast-void-and-LogMessageVoidify-needed-in-logging-macros.md, I understand the reason for using LogMessageVoidify, while it turns the LOG_IF from ostream into void. If someone wants to wrap LOG_IF or VLOG, it causes error:

#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel))

#define MYLOG \
    static_cast<void>(0),             \
      !(condition)                  \
          ? (void)0                 \
          : google::logging::internal::LogMessageVoidify() & VLOG(1)

The code above causes errors like error: no match for 'operator&' (operand types are 'google::LogMessageVoidify' and 'void') I can't use VLOG_IF in my wrapper for other reasons.

So I want to know if I can use NullStream instead like:

#define LOG_IF(severity, condition) \
      !(condition)                  \
          ? google::NullStream().stream()                \
          :  LOG(severity)

Thus LOG_IF is still an ostream and we can wrap it. What's the difference between using google::NullStream and LogMessageVoidify?

JensHuthmann commented 3 days ago

I am using this as a work around for #933

#ifndef GOOGLE_STRIP_LOG
#define GOOGLE_STRIP_LOG 0
#endif

#include <glog/logging.h>

#define MY_LOG_INT_(severity, lvl) \
    if constexpr (GOOGLE_STRIP_LOG >= lvl) {} \
    else LOG(severity)

#define MY_LOGIF_INT_(severity, test, lvl) \
    if constexpr (GOOGLE_STRIP_LOG >= lvl) {} \
    else LOG_IF(severity, test)

#define SEVERITY_LVL_INFO (1)
#define SEVERITY_LVL_WARNING (2)
#define SEVERITY_LVL_ERROR (3)
#define SEVERITY_LVL_FATAL (4)

#define MY_LOG(severity) \
    if constexpr (GOOGLE_STRIP_LOG >= SEVERITY_LVL_##severity) {} \
    else LOG(severity)

#define MY_LOG_BUILD(severity, code) \
    if constexpr (GOOGLE_STRIP_LOG >= SEVERITY_LVL_##severity) {} \
    else { code }

#define MY_LOG_IF(severity, test) MY_LOGIF_INT_(severity, test, SEVERITY_LVL_##severity)