使用 assert 与 exit 或反之有哪些优点或含义?

What are the advantages or implications of using assert vs exit or vice versa?

据我所知,调用 assert(e),其中 e 是一个布尔表达式,执行大致类似于 if (!e) { printf("%s:%d: failed assertion `%s'\n", __FILE__, __LINE__, e); abort(); } 的操作,如果给定的表达式是不对。

另一方面,如果不使用 assert,我可能会写一些类似 if (!e) { fprintf(stderr, "custom error message.\n"); exit(1); } 的东西,天真地感觉它更干净、更好。

忽略 assert 可以使用 NDEBUG 标志全局关闭,您认为其中一个比另一个有什么其他优势?我的区别是否正确,或者两者之间是否存在我不知道的概念差异,这让条件程序终止的两种方式都有自己的利基用例?如果是后者,请说明。谢谢。

what other advantage do you think one has over the other?

使用宏是因为您希望能够通过条件编译将其删除。换句话说,您甚至不希望代码出现在二进制文件中。

Have I got the distinction right, or are there conceptual differences between the two which I am unaware of that let the two ways of conditional program termination have their own niche use cases?

嗯,即使您使用 1 作为“不成功”的退出代码,exit()abort() 的行为也不相同。后者旨在立即终止程序而无需进一步工作,并可能触发调试提示或保存进程图像 space(尽管它的具体作用取决于提供它的供应商)。前者通过atexit()调用注册函数。还有其他停止方法,请参阅 quick_exit()_Exit()

对于 C++,有更多关于行为差异的考虑,例如堆栈帧中变量的析构函数是否为 运行,全局析构函数是否为 运行,如果在执行此操作时抛出异常会发生什么,等等

assert最大的好处就是明目张胆。如果你看到 assert(some_condition) 那么你就知道作者的意图是什么(即 some_condition 总是 true)。对于您的内联版本,在我真正阅读您的 if 块并意识到您将显示一条错误消息并终止程序之前,我无法假设意图。

不太重要的原因包括 assert 减少了 copy/paste 错误,some_condition 自动转换为字符串(包括保留变量名),并且工具可以理解它。

'assert' 是一个代码自动测试工具。有时,即使满足导致断言执行的条件,程序也不应停止其在客户端(发布版本)的工作。 例如:

   switch(color)
   {
      case red:
        //...
      break;
      
      case green:
        //...
      break;
      
      default:
        assert(false && "unexpected color value. 'enum color' was modified?");
   }

另一个例子:

   if ( OkOrFailEnum::OK != result )
   {
      assert(false && "data access fail");
      throw std::runtime_error("Can not get index " + std::to_string(index));
   }    

同时'assert'是一个代码注释工具

   inline unsigned Sum(unsigned* pPos, unsigned* pOffset)
   {
     assert(nullptr != pPos);                             // \
     assert(nullptr != pOffset);                          // | preconditions
     assert(*pPos + *pOffset < *pOffset && "Overflow?");  // /
     
     return *pPos + *pOffset;
   }

断言:

 assert(*pPos + *pOffset < *pOffset && "Overflow?");

意味着 Sum(..) 函数不能正确处理大数额,它必须在调用函数之前做一些检查。