用于 switch 语句的便捷调试宏






3.55/5 (9投票s)
1999年11月27日
2分钟阅读

68559
一个宏,
在编写 switch 语句时,你的代码通常会处理 switch 控制变量可能采取的每种情况。例如,如果你有一个 MFC 对话框,其中包含一个组合框或单选按钮组,并且有一个整数成员变量连接到该组合框或单选按钮组,以保存用户的选择,你可能会有一个 switch 语句,该语句根据该变量的值采取操作。
对于像上述示例这样的 switch 语句,你通常知道在正常情况下,代码永远不会到达 switch 语句中的 default 部分。如果代码应该命中 default 部分,则表明 switch 语句或 UI 处理代码中存在错误。断言就是用来捕获这类情况的——即如果代码正常工作,则不应发生的情况。
我创建了这个调试宏,我富有想象力地将其命名为 DEFAULT_UNREACHABLE
,你可以将其放在 switch 语句的末尾,以确保任何引入导致执行绕过未处理的 switch 语句的错误都被捕获。该宏通过生成断言失败来让你知道有问题。
- 调试版本:强制断言失败,以便 MSVC 会直接在出现错误的位置将你转到调试器中。
- VC 6 及更高版本的发布版本:包含一个
__assume
语句,作为对编译器的优化提示。根据 VC 文档,这会减小 switch 语句的编译代码大小。 - VC 5 及更早版本的发布版本:不执行任何操作。
你可能会想知道,“为什么发布版本不执行任何操作?最终结果与没有宏的情况相同吗?” 这确实是真的,但请记住,调试版本才是这里的主力。当你测试你的调试版本时,你将捕获并修复由宏标记的错误,确保代码永远不会到达 default 部分。这意味着发布版本不需要在 default 部分包含任何代码,因为(与我一起说)代码永远不会到达那里。
废话不多说,以下是宏的代码以及一个显示如何使用它的示例。
#ifdef _DEBUG #define DEFAULT_UNREACHABLE default: ASSERT(0); break #elif _MSC_VER >= 1200 #define DEFAULT_UNREACHABLE default: __assume(0); break #else #define DEFAULT_UNREACHABLE default: break #endif;
示例用法:想象一个带有用于选择星期几的单选按钮的对话框。有一个变量 m_nDay 连接到这些单选按钮。
void CMyDialog::OnOK() { UpdateData(); switch ( m_nDay ) { case 0: case 6: // do something for the weekend... break; case 1: case 2: case 3: // something else for Mon-Wed... break; case 4: case 5: // and something else for Thu-Fri break; DEFAULT_UNREACHABLE; }
作为代码的作者,我知道 m_nDay 不应该包含除 0 到 6 之外的任何值,如果它确实包含,则表明存在错误。因此,我在 switch 语句中放置了 DEFAULT_UNREACHABLE
宏,如果发生这种情况,它会提醒我。
最后需要说明的是,最新的winnt.hSDK 中的文件包含一个 DEFAULT_UNREACHABLE
宏,但它不如这里的宏好。SDK 版本只是简化为 __assume
语句,并且没有提供任何帮助进行调试的机制。