无法访问代码的断言

在开发过程中,当必须阻止某些代码路径到达控制流时,你可以使用 assert(0) 来指示这样的条件是错误的:

switch (color) {
    case COLOR_RED:
    case COLOR_GREEN:
    case COLOR_BLUE:
        break;

    default:
        assert(0);
}

只要 assert() 宏的参数计算为 false,宏就会将诊断信息写入标准错误流,然后中止程序。此信息包括 assert() 语句的文件和行号,在调试时非常有用。可以通过定义宏 NDEBUG 来禁用断言。

发生错误时终止程序的另一种方法是使用标准库函数 exitquick_exitabortexitquick_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 通常是一个非常严格的终止,它会禁止为 exitquick_exit 运行安装的清理处理程序。