库实现者如何决定何时抛出异常与表现未定义的行为?

jwa*_*alk 4 c++ exception

特别考虑 C++string类构造函数规范,我们有:

string (const string& str, size_t pos, size_t len = npos);
string (const char* s, size_t n);
Run Code Online (Sandbox Code Playgroud)

它们本质上具有相同的形式/意图,除了 string 和 c-string。然而,异常规范却非常不同:

如果 pos 大于 str 的长度,则会抛出 out_of_range 异常。

如果 n 大于 s 指向的数组,则会导致未定义的行为。

我想知道这是为什么?除了性能之外,什么时候抛出异常与允许“未定义的行为”是一个好主意?答案似乎取决于以下因素:

  • 客户端先验地识别故障的能力(即,与从客户端明确使用的空堆栈中弹出相比,客户端识别文件访问潜在问题的可能性要小得多)
  • 客户对处理潜在问题的兴趣(即可能更经常需要处理文件访问问题,因为不太可预测?)
  • 从实现者的角度来看什么“最有意义”(也许字符串版本会抛出异常,因为它与 C++ 风格更相关,因此与异常语义相关)

Ren*_*nzo 5

两种情况的区别在于,在第一种情况下,实现可以检查传递的参数是否有错误,而在第二种情况下则不可能无法检查哪个是参数)字符串的长度,因为只传递了一个指针)。

所以一般规则可能如下:

  1. 如果可能,检查可能的故障情况并引发异常;
  2. 否则,从实现者的角度来看,什么也做不了,并且在函数规范中记录了未定义行为的可能性。