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

13

这是重载 (4) 这里

在“Exceptions”部分,具有pos1和/或pos2参数的重载2,3,5,6被命名为抛出std::out_of_range

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

实现是否抛出异常取决于实现方式?

在GCC 7的libstdc++中,它调用了char_traits<char>::lengthchar_traits<char>::compare。它们似乎不能抛出异常,但未标记为noexcept


2
说实话,我不确定为什么这个问题会得到这么多赞.. Clang 的写法是:int compare(const value_type* __s) const _NOEXCEPT; GCC 也是这样的:int compare(const _CharT* __s) const _GLIBCXX_NOEXCEPT; https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/basic_string.h#L2988 - Brandon
看起来这取决于实现,但从逻辑上讲,它似乎应该是“noexcept”。 - anonmess
1
我猜我们需要一位语言律师来得到真正的答案...但我认为,标准不要求std::string将字符串存储为CharT *,以允许小字符串优化。然而,这也意味着我们可能需要进行一些转换才能实际进行“比较”。这种转换可能需要分配内存,可能会用尽内存,因此可能会抛出异常。因此,标准无法强制执行实现的noexcept,尽管它们在实践中仍然可能是noexcept - jan.sende
1个回答

2
除了析构函数、交换函数、移动构造函数和移动赋值运算符外,标准仅在函数具有宽松约束时将其标记为noexcept,即该函数没有前置条件。此重载要求参数为以空字符结尾的字符串,因此标准不将其标记为noexcept
该理由在N3248中指定:

Functions marked noexcept are difficult to test

When a function is marked with noexcept it becomes impossible to flag test failures, notably in test drivers, by throwing an exception. A common example would be code that validates preconditions on entry to a function:

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

When validating such defensive checks from a test driver, a reasonable approach is to register an assert-handler that throws a well-defined precondition-violated exception, which the test driver catches to ensure that the appropriate asserts are indeed in place.

...

Now we might argue that calling the function out-of-contract, when the vector is empty, is undefined behavior so we should not expect any guarantees. The problem is that undefined behavior is being specified by the library; to the compiler, this code is perfectly well defined and, if assert throws an exception, the program must terminate in a well-specified manner, thwarting the test driver.

Note that the issue here is not that we are using assertions to find bugs in our own library implementations, but rather in user code that incorrectly calls into our library. If we remove the ability to test these defensive assertions, we may get them wrong, and thus put our users at risk for committing far more serious errors than propagating an unexpected exception.


顺便提一下,由于[res.on.exception.handling]/5
引用块: 实现可以通过添加非抛出异常规范来加强非虚函数的异常规范。
... libstdc++libc++可以将此重载标记为noexcept

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接