这是一个很好的方式来嵌入调试消息在我的程序? (宏) [英] Is this a good way to embed debugging message in my program? (Macros)

查看:89
本文介绍了这是一个很好的方式来嵌入调试消息在我的程序? (宏)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Debug.h文件中,我有以下:

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

在其他地方,我可以写如下

  void process数据数据)
{
DEBUG(Function'process'starts);
// Blah blah
//更多blah blah ...
DEBUG(Function'process'returns);
}

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



此外,这种做法是否正确?

解决方案

p>这里有一个替代方法,使用编译器的死代码删除:

  #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&
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 =='\\\
'); }
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&运算符<< (std :: ostream&(* m)(std :: ostream&))const {
has_endl_ = same_manip(m,std :: endl);
os_<< m;
return * this;
}
template< typename T>
const dbglog&运算符<< (const T& v)const {
has_endl_ = has_endl(v);
os_<< v;
return * this;
}
};

现在,您可以添加一个类似这样的简单消息(注意,换行符是可选的) p>

  DEBUG(A simple message); 
DEBUG(一个简单的消息with newline \\\
);
DEBUG(带有endl的简单消息)< std :: endl;

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

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


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(;true==false;)
#endif

In other places, I may write something like

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

Will the compiler optimize away the for(;true==false;); ?

Also, is this kind of practice okay? If not, what would be a better way?

Thanks!

解决方案

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;

这篇关于这是一个很好的方式来嵌入调试消息在我的程序? (宏)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆