在调试模式或我正在进行测试时,我需要打印大量各种信息,所以我使用这种方法:
#ifdef TESTING
// code with lots of debugging info
#else
// clean code only
#endif // TESTING`
这是一个好方法,还是有其他简单而优雅的方法?
但是这样,我在两个地方重复相同的代码,如果稍后要在代码中进行更改,我必须在两个地方都这样做,这很费时且容易出错。
感谢。
我正在使用MS Visual Studio。
答案 0 :(得分:17)
您可以使用宏来打印调试信息,然后在发布版本中将该宏定义为空。
如,
#ifdef _DEBUG
#define DEBUG_PRINT(x) printf(x);
#else
#define DEBUG_PRINT(x)
#endif
使用此方法,您还可以添加更多信息,例如
__LINE__
__FILE__
自动调试信息。
答案 1 :(得分:6)
写一次
#ifdef _DEBUG
const bool is_debig = true;
#else
const bool is_debig = false;
#endif
然后
template<bool debug>
struct TemplateDebugHelper {
void PrintDebugInfo(const char* );
void CalcTime(...);
void OutputInfoToFile(...);
/// .....
};
// Empty inline specialization
template<>
struct TemplateDebugHelper<false> {
void PrintDebugInfo(const char* ) {} // Empty body
void CalcTime(...) {} // Empty body
void OutputInfoToFile(...) {} // Empty body
/// .....
};
typedef TemplateDebugHelper<is_debug> DebugHelper;
DebugHelper global_debug_helper;
int main()
{
global_debug_helper.PrintDebugInfo("Info"); // Works only for is_debug=true
}
答案 2 :(得分:2)
在包含标题
上使用类似的定义#ifdef TESTING
#define DEBUG_INFOS(_X_) CallYourDebugFunction(_X_ )
#else
#define DEBUG_INFOS(_X_) ((void)0)
#endif
然后在代码上只使用它
...
DEBUG_INFOS("infos what ever");
RestOfWork();
...
您还可以使用和搜索 ASSERT 和 TRACE 宏,并使用sysinternals中的 DebugView 从跟踪中读取输出实时,或跟踪ASSERT的问题。 ASSERT和TRACE做类似的工作,你可以从中获得想法。
评论:我使用TESTING声明,因为我在问题上看到了这一点。
答案 3 :(得分:2)
使用Log4Cxx,而不是滚动自己的日志记录。 Log4Cxx包是高度可配置的,支持基于重要性/严重性的不同级别的日志记录,并支持多种形式的输出。
此外,除非必须进行超级优化的非常关键的代码,否则我建议在代码中保留日志记录语句(假设您使用Log4Cxx),但只需调低日志记录级别。这样,可以动态启用日志记录,如果您的某个用户遇到难以复制的错误,这可能会非常有用......只需指导他们如何配置更高的日志记录级别。如果您完全忽略了可执行文件的日志记录,那么就无法在该字段中获得有价值的调试输出。
答案 4 :(得分:1)
您可以使用类似boost::log设置严重程度级别的内容。
void init()
{
logging::core::get()->set_filter
(
flt::attr< logging::trivial::severity_level >("Severity") >= logging::trivial::info
);
}
int main(int, char*[])
{
init();
BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
BOOST_LOG_TRIVIAL(info) << "An informational severity message";
BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
BOOST_LOG_TRIVIAL(error) << "An error severity message";
BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";
}
我认为pantheios也有类似的东西。
答案 5 :(得分:0)
我正在用C编写嵌入式系统。 在我的程序中,我正在使用以下宏:
#define _L log_stamp(__FILE__, __LINE__) #define _LS(a) log_string(a) #define _LI(a) log_long(a) #define _LA(a,l) log_array(a,l) #define _LH(a) log_hex(a) #define _LC(a) log_char(a) #define ASSERT(con) log_assert(__FILE__, __LINE__, con)
当我发布版本时,我只需关闭#define DEBUG指令,所有宏都会变空。 请注意,它不会消耗发行版中的任何CPU周期和内存。 宏是保存日志信息的唯一方法:记录完成的位置 (文件和行号)。
如果我需要这些信息,我会使用:
_L;_LS("this is a log message number ");_LI(5);
否则没有_L
指令。
答案 6 :(得分:0)
有一种简单的方法,适用于大多数编译器:
#ifdef TESTING
#define DPRINTF( args ) printf args
#else
#define DPRINTF( args ) ((void)0)
#endif
接下来,在源代码中,您应该将其用作:
DPRINTF(("Debug: value a = %d, value b = %d\n", a, b));
缺点是你必须使用双括号,但在旧的C和C ++中 标准variadic宏不受支持(仅作为编译器扩展)。