|嵌入式开发:在C中使用断言的8个技巧

|嵌入式开发:在C中使用断言的8个技巧

文章图片

|嵌入式开发:在C中使用断言的8个技巧

文章图片

【|嵌入式开发:在C中使用断言的8个技巧】|嵌入式开发:在C中使用断言的8个技巧

嵌入式开发人员可用的最强大的错误压缩工具之一是断言宏 。 尽管断言很强大 , 但却很少看到它被实现 , 并且在使用它的情况下 , 实现要么有缺陷 , 要么不正确 。 以下七个技巧不仅有助于阐明何时何地使用断言 , 而且还有助于阐明如何开始正确使用它 。

技巧1 – 记住断言的定义断言对于许多开发人员来说是一个令人困惑的话题 , 因为他们很容易以一种并非设计用于的方式使用断言 。关于断言的最清晰定义是:“断言是程序中特定点的布尔表达式 , 除非程序中存在错误 , 否则它将为真 。 ”
检查上述断言定义的开发人员应注意三个关键点:
断言将表达式评估为真或假
断言是对代码中特定点的系统状态的假设
断言正在验证系统假设 , 如果不正确 , 则表明代码中存在错误
技巧2 – 使assert来验证函数的前置条件
断言在按合同设计的环境中工作得很好 , 其中嵌入式开发人员已经明确定义了函数的先决条件 。断言可用于检查函数的输入是否满足前提条件 。 以下代码片段为例:

函数的状态输入应属于定义的系统状态 。 如果 State 在有效状态之外 , 那不是错误而是bug!断言可用于验证状态有效的假设 , 如下图所示:

如果状态不小于最大值 , 则断言表达式将被评估为假 , 然后程序执行将停止 。停止程序执行使开发人员可以很容易地立即看到代码出错的地方 , 而不是等很久以后 。
技巧3 – 使用断言来验证函数的后置条件
断言还可用于验证有关按合同设计环境中函数输出的假设 。 例如 , 如果先前定义的System_StateSet 函数返回 SystemState 变量 , 开发人员会期望它也在预期范围内 。 可以使用断言来监视错误 , 如下图所示:

检查上面的代码 , 嵌入式开发人员可能会觉得这些检查毫无价值 。 刚刚设置的 SystemState怎么会大于 SYSTEM_STATE_MAX?答案是它不应该是这样 , 这就是为什么如果它确实发生了变化 , 可能是通过中断或并行线程 , 断言将立即标记错误 。
技巧4 – 不要使用断言进行错误处理
在记住断言的定义后 , 开发人员应该牢记断言是用于检测错误而不是用于错误处理 。 错误处理是旨在响应不正确的用户输入和意外事件序列的软件 。 错误预计会在系统中发生 , 但仅仅因为输入无效并不意味着代码中存在错误 。 错误处理应与错误搜寻分开 。 不正确使用断言的一个典型例子是在尝试打开文件进行读取时检查文件指针 。 图4显示了一个示例 。

读者可以清楚地看到 , 尝试打开文件的结果取决于文件系统和用户数据的状态 , 与代码中的错误完全无关 。 而不是断言 , 嵌入式开发人员应该编写一个错误处理程序 , 如果文件不存在 , 它会创建它 , 它将一些默认的可用数据用于进一步发生在代码中的操作 。
技巧5 – 断言用于开发而非生产
断言宏的初衷是在开发期间启用它 , 然后在生产中禁用它 。 启用和禁用断言是使用宏 NDEBUG 完成的 。 正确实现的断言在禁用时应该对嵌入式系统几乎没有影响 。 问题是 , 如果在开启它们的情况下执行测试 , 应该这样做以捕获任何错误 , 现在关闭它们会导致交付的产品处于与测试状态不同的状态 。