std :: string :: compare(const char *)会抛出异常吗?

时间:2019-07-10 13:27:04

标签: c++ language-lawyer

这是重载(4)here

在“异常”部分中,重载2、3、5、6(具有pos1和/或pos2参数)被命名为抛出std::out_of_range

重载(4)没有“ pos”参数,但未标记为noexcept

是否抛出该结果取决于实现?

在GCC 7的libstdc ++中,它调用char_traits<char>::lengthchar_traits<char>::compare。这些似乎无法抛出,但没有标记为noexcept

1 个答案:

答案 0 :(得分:1)

除析构函数,交换函数,移动构造函数和移动赋值运算符外,该标准仅在具有wide contract的情况下标记函数noexcept,即没有先决条件。此重载要求参数是一个以空值结尾的字符串,因此标准不会将其标记为noexcept

有理在N3248中指定:

  

标记为noexcept的功能很难测试

     

当一个函数标有noexcept时,就不可能标记测试失败,   特别是在测试驱动程序中,会引发异常。一个常见的例子是代码   可以验证输入函数的先决条件:

T& std::vector<T>::front() noexcept {
 assert(!this->empty());
 return *this->data();
}
     

验证测试驾驶员的这种防御性检查时,一种合理的方法是   注册一个引发明确定义的违反先决条件的异常的断言处理程序,   测试驱动程序捕获的内容,以确保确实存在适当的assert   地方。

     

...

     

现在我们可能会争辩说,当vector为   空,是未定义的行为,因此我们不应期望任何保证。问题在于该库正在指定未定义的行为。对于编译器,此代码是   定义明确,并且如果assert引发异常,则程序必须终止   以明确的方式阻止测试驱动程序。

     

请注意,这里的问题不是我们在使用断言来查找自己的错误   库实现,而是在错误地调用我们库的用户代码中。   如果我们取消测试这些防御性断言的能力,我们可能会弄错它们,   因此,与传播相比,我们的用户有犯更严重错误的风险   意外的异常。


顺便说一句,由于[res.on.exception.handling]/5

  

实现可以通过添加非抛出异常规范来增强非虚函数的异常规范。

... libstdc++libc++可以自由标记此重载noexcept