无法访问代码的断言
在开发过程中,当必须阻止某些代码路径到达控制流时,你可以使用 assert(0) 来指示这样的条件是错误的:
switch (color) {
case COLOR_RED:
case COLOR_GREEN:
case COLOR_BLUE:
break;
default:
assert(0);
}
只要 assert() 宏的参数计算为 false,宏就会将诊断信息写入标准错误流,然后中止程序。此信息包括 assert() 语句的文件和行号,在调试时非常有用。可以通过定义宏 NDEBUG 来禁用断言。
发生错误时终止程序的另一种方法是使用标准库函数 exit,quick_exit 或 abort。exit 和 quick_exit 采用可以传递回你环境的参数。abort()(以及 assert)可能是一个非常严重的程序终止,并且可能无法执行在执行结束时执行的某些清理。
assert() 的主要优点是它可以自动打印调试信息。调用 abort() 的优点是不能像断言一样禁用它,但它可能不会导致显示任何调试信息。在某些情况下,同时使用这两种结构可能是有益的:
if (color == COLOR_RED || color == COLOR_GREEN) {
...
} else if (color == COLOR_BLUE) {
...
} else {
assert(0), abort();
}
启用断言后,assert() 调用将打印调试信息并终止程序。执行永远不会到达 abort() 调用。当断言被禁用时,assert() 调用什么都不做,并且调用 abort()。这可确保程序始终终止此错误条件; 启用和禁用断言仅影响是否打印调试输出。
你永远不应该在生产代码中留下这样的信息,因为调试信息对最终用户没有帮助,因为 abort 通常是一个非常严格的终止,它会禁止为 exit 或 quick_exit 运行安装的清理处理程序。