Is this a good way to embed debugging message in my program? (Macros)

前端 未结 3 940
说谎
说谎 2021-01-22 08:52

in the Debug.h file, I have the following:

#ifdef DEBUG_FLAG
    #define DEBUG(msg) std::cerr << #msg << std::endl
#else
    #define DEBUG(msg) for(;         


        
相关标签:
3条回答
  • 2021-01-22 09:30

    You also need the while (0) for your debug macro. Will be very painful to debug if/else cases without it (if you are lucky, you will get a compiler error). See this question for more details.

    0 讨论(0)
  • 2021-01-22 09:33

    Here's an alternative, that uses the compiler's dead code removal:

    #define DEBUG(msg) if (!DEBUG_ENABLED) {} \
                       else dbglog() << __FILE__ << ":" << __LINE__ << " " << msg
    #ifdef DEBUG_FLAG
    #define DEBUG_ENABLED 1
    #else
    #define DEBUG_ENABLED 0
    #endif
    

    The dbglog instance is a ostream wrapper that detects if the log line ended with a newline or not. If not, it adds one.

    struct dbglog {
        std::ostream &os_;
        mutable bool has_endl_;
        dbglog (std::ostream &os = std::cerr) : os_(os), has_endl_(false) {}
        ~dbglog () { if (!has_endl_) os_ << std::endl; }
        template <typename T> static bool has_endl (const T &) { return false; }
        static bool has_endl (char c) { return (c == '\n'); }
        static bool has_endl (std::string s) { return has_endl(*s.rbegin()); }
        static bool has_endl (const char *s) { return has_endl(std::string(s)); }
        template <typename T>
        static bool same_manip (T & (*m)(T &), T & (*e)(T &)) { return (m == e); }
        const dbglog & operator << (std::ostream & (*m)(std::ostream &)) const {
            has_endl_ = same_manip(m, std::endl);
            os_ << m;
            return *this;
        }
        template <typename T>
        const dbglog & operator << (const T &v) const {
            has_endl_ = has_endl(v);
            os_ << v;
            return *this;
        }
    };
    

    Now, you can add a simple message like this (note, the newline is optional):

    DEBUG("A simple message");
    DEBUG("A simple message with newline\n");
    DEBUG("A simple message with endl") << std::endl;
    

    Or, if you want to add more debugging information:

    DEBUG("Entering: ") << __func__ << ", argc=" << argc << ", argv=" << argv;
    //...
    DEBUG("Leaving: ") << __func__ << std::endl;
    
    0 讨论(0)
  • 2021-01-22 09:46

    You don't need:

    #define DEBUG(msg) for(;;)

    at all. If you just have it as:

    #define DEBUG(msg)

    then the expression will be literally blank and won't require a semicolon at all.

    EDIT: And actually, having sole semicolons will not cause crashes or compiler errors.

    0 讨论(0)
提交回复
热议问题