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

Bul*_*net 12 c++ language-lawyer

这是过载(4)在这里

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

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

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

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

xsk*_*xzr 2

除了析构函数、交换函数、移动构造函数和移动赋值运算符之外,该标准noexcept仅在函数具有宽契约时才标记该函数,即它没有先决条件。此重载要求参数是一个以 null 结尾的字符串,因此标准不会将其标记为noexcept.

N3248中指定了有理数:

标记的功能noexcept难以测试

当一个函数被标记为 时,noexcept就不可能通过抛出异常来标记测试失败,特别是在测试驱动程序中。一个常见的示例是验证函数入口前提条件的代码:

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

当验证来自测试驱动程序的此类防御性检查时,合理的方法是注册一个断言处理程序,该处理程序抛出一个定义良好的违反先决条件的异常,测试驱动程序捕获该异常以确保适当的确实assert就位。

...

现在我们可能会争辩说,当 为空时,调用合同外的函数vector是未定义的行为,因此我们不应该期望任何保证。问题是库指定了未定义的行为;对于编译器来说,这段代码是完美定义的,如果assert抛出异常,程序必须以明确指定的方式终止,从而阻碍测试驱动程序。

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


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

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

...libstdc++并且libc++可以自由地标记此过载noexcept