使用预处理器进行调试

C++ 程序员有时也会使用类似的技术有条件地执行用于调试的代码。这种想法是:程序所
包含的调试代码仅在开发过程中执行。当应用程序已经完成,并且准备提交时,
就会将调试代码关闭。可使用 NDEBUG 预处理变量实现有条件的调试代码:
int main()
{
#ifndef NDEBUG
cerr << "starting main" << endl;
#endif
// ...
如果 NDEBUG 未定义,那么程序就会将信息写到 cerr 中。如果 NDEBUG 已

经定义了,那么程序执行时将会跳过 #ifndef 和 #endif 之间的代码。

默认情况下,NDEBUG 未定义,这也就意味着必须执行 #ifndef 和 #endif
之间的代码。在开发程序的过程中,只要保持 NDEBUG 未定义就会执行其中的调
试语句。开发完成后,要将程序交付给客户时,可通过定义 NDEBUG 预处理变量,
(有效地)删除这些调试语句。大多数的编译器都提供定义 NDEBUG 命令行选项:
$ CC -DNDEBUG main.C
这样的命令行行将于在 main.c 的开头提供 #define NDEBUG 预处理命令。
预处理器还定义了其余四种在调试时非常有用的常量:

__FILE__ 文件名
__LINE__ 当前行号
__TIME__ 文件被编译的时间
__DATE__ 文件被编译的日期
可使用这些常量在错误消息中提供更多的信息:


if (word.size() < threshold)
cerr << "Error: " << _ _FILE_ _
<< " : line " << _ _LINE_ _ << endl
<< " Compiled on " << _ _DATE_ _
<< " at " << _ _TIME_ _ << endl
<< " Word read was " << word
<< ": Length too short" << endl;

如果给这个程序提供一个比 threshold 短的 string 对象,则会产生下面
的错误信息:
Error: wdebug.cc : line 21
Compiled on Jan 12 2005 at 19:44:40
Word read was "foo": Length too short


另一个常见的调试技术是使用 NDEBUG 预处理变量以及 assert 预处理宏。
assert 宏是在 cassert 头文件中定义的,所有使用 assert 的文件都必须包含
这个头文件。
预处理宏有点像函数调用。assert 宏需要一个表达式作为它的条件:
assert(expr)
只要 NDEBUG 未定义,assert 宏就求解条件表达式 expr,如果结果为
false,assert 输出信息并且终止程序的执行。如果该表达式有一个非零(例如,
true)值,则 assert 不做任何操作。
与异常不同(异常用于处理程序执行时预期要发生的错误),程序员使用
assert 来测试“不可能发生”的条件。例如,对于处理输入文本的程序,可以
预测全部给出的单词都比指定的阈值长。那么程序可以包含这样一个语句:
assert(word.size() > threshold);
在测试过程中,assert 等效于检验数据是否总是具有预期的大小。一旦开
发和测试工作完成,程序就已经建立好,并且定义了 NDEBUG。在成品代码中,
assert 语句不做任何工作,因此也没有任何运行时代价。当然,也不会引起任
何运行时检查。assert 仅用于检查确实不可能的条件,这只对程序的调试有帮
助,但不能用来代替运行时的逻辑检查,也不能代替对程序可能产生的错误的检
测。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值