有用的调试宏






4.63/5 (9投票s)
1999年12月15日

136613

1283
一组方便的调试宏设施,
MFC 附带了一组有用的调试宏。我们都多次使用过这些宏,并且对它们非常熟悉。然而,有多少次,您在编写非 MFC 代码时,希望可以使用相同的宏?标准 C/C++ 仅提供一个至少与 MFC ASSERT 宏相似的宏,即 assert。但是,这个特定的断言宏不如 MFC 版本优雅,MFC 版本会直接将您带到断言代码所在的行。
或者,您可能有一些调试需求超出了 MFC 宏提供的范围。例如,您可能正在拼命尝试追踪内存溢出错误。
希望本文能为您解决这些问题!
在下载文件中找到的头文件 <debug.h> 定义了几个用于调试代码的宏。其中许多宏对于 MFC 程序员来说很熟悉,因为它们使用相同的名称并提供相同的功能。事实上,如果在此头文件之前包含了 MFC,则使用这些宏的 MFC 版本。除了 MFC 宏之外,还定义了其他几个宏以提供 Microsoft 忘记的功能。下面,您将找到对现有宏的一般描述。
ASSERT
ASSERT 宏与同名的 MFC 宏相同。它用于在调试构建期间(当定义了 _DEBUG 时)在代码中断言条件。如果断言失败,程序将在断言所在的行中断。
示例
ASSERT(a < 1);
VERIFY
VERIFY 宏与同名的 MFC 宏相同。它与 ASSERT 类似,但即使对于发布构建也会评估条件,尽管只有在调试构建中才会发生中断。
示例
VERIFY(pWnd = GetDlgItem(IDC_MYEDIT));
TRACE
TRACE 宏与同名的 MFC 宏相同。它用于将文本发送到调试输出窗口。它的语法类似于 printf 的语法。
示例
TRACE("Name: %s\n", obj.name());
INFO
INFO 宏类似于 TRACE 宏。与 TRACE 不同,INFO 在文本前面加上文件名和调用 INFO 的行号,并附加一个新行。
示例
INFO("Name: %s\n", obj.name());
DBG
DBG 宏仅用于调试构建。
示例
DBG(AfxMessageBox("I'm here!"));
BREAK
BREAK 宏用于强制程序仅在调试构建时中断。当调用 BREAK 的行运行时,程序将暂停,调试器将转到该行。
示例
BREAK();
DECL_DOG_TAG 和 CHECK_DOG_TAG
这些宏是此头文件中最复杂的调试宏中的两个。它们用于帮助检测由内存溢出导致的内存损坏。我很久以前从一篇杂志文章中获得了这项技术。不幸的是,我不记得是在哪里。如果有人知道,请给我发电子邮件,以便我能够适当地认可原始作者。
要使用 "狗牌",您首先必须使用 DECL_DOG_TAG 在类定义中声明它们。之后,您可以通过在代码中调用 CHECK_DOG_TAG 来验证内存的完整性。通常,您将在一个类中声明两个狗牌,一个作为第一个类成员,一个作为最后一个。定义一个通过使用这些狗牌来验证类完整性的方法也很有帮助。然后,客户端代码可以通过调用此方法来检查类的有效性。请参阅下面的示例以演示这一点。
示例
class MyClass { private: DECL_DOG_TAG(MyClassBegin); // All other class data should be declared here. Removed for brevity. private: DECL_DOG_TAG(MyClassEnd); #ifdef _DEBUG public: void VerifyIntegrity() const // Call this to check the dog tags { CHECK_DOG_TAG(MyClassBegin); CHECK_DOG_TAG(MyClassEnd); } #endif }; // Later in the code: void func(MyClass& obj) { DBG(obj.VerifyIntegrity()); // Check the object's integrity }
使用上述代码,如果对象的完整性已损坏(通常是由于您的代码中出现内存溢出),则在调用 CHECK_DOG_TAG 宏中的 VerifyIntegrity 时,ASSERT 将失败。
希望您发现这个头文件有用。如果您知道任何其他调试宏,请给我写信。我将在该头文件的后续版本中添加它们。