这是在我的程序中嵌入调试消息的好方法吗? (宏)

时间:2012-07-14 02:07:47

标签: c++ debugging macros

在Debug.h文件中的

,我有以下内容:

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

在其他地方,我可能会写类似

的内容
void process (Data data)
{
    DEBUG("Function 'process' starts");
    // Blah blah
    // More blah blah...
    DEBUG("Function 'process' returns");
}

编译器是否会优化for(; true == false;); ?

另外,这种做法还好吗?如果没有,那会是更好的方式吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

您不需要:

#define DEBUG(msg) for(;;)

完全没有。如果您只是将其作为:

#define DEBUG(msg)

然后表达式将字面上为空白,并且根本不需要分号。

编辑:实际上,使用单独的分号不会导致崩溃或编译错误。

答案 1 :(得分:2)

这是一个替代方案,它使用编译器的死代码删除:

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

dbglog实例是ostream包装器,用于检测日志行是否以换行符结束。如果没有,它会添加一个。

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;
    }
};

现在,您可以添加这样的简单消息(注意,换行符是可选的):

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

或者,如果您想添加更多调试信息:

DEBUG("Entering: ") << __func__ << ", argc=" << argc << ", argv=" << argv;
//...
DEBUG("Leaving: ") << __func__ << std::endl;

答案 2 :(得分:0)

您还需要while (0)作为调试宏。在没有它的情况下调试if / else情况会非常痛苦(如果你很幸运,你会得到编译器错误)。有关详细信息,请参阅this question