C++ std::string::compare(const char*)能否引发异常?

C++ std::string::compare(const char*)能否引发异常?,c++,language-lawyer,C++,Language Lawyer,这是过载(4) 在“异常”部分中,重载2、3、5、6(具有pos1和/或pos2参数)被命名为抛出std::out_of_range 重载(4)没有“pos”参数,但未标记为noexcept 它是否抛出,取决于实现吗 在GCC7的libstdc++中,它调用char\u traits::length和char\u traits::compare。除了析构函数、交换函数、移动构造函数和移动赋值运算符之外,这些函数似乎不能抛出,但没有标记为noexcept,标准仅在函数有一个,即没有先决条件时才标记

这是过载(4)

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

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

它是否抛出,取决于实现吗


在GCC7的libstdc++中,它调用
char\u traits::length
char\u traits::compare
。除了析构函数、交换函数、移动构造函数和移动赋值运算符之外,这些函数似乎不能抛出,但没有标记为
noexcept
,标准仅在函数有一个,即没有先决条件时才标记函数
noexcept
。此重载要求参数为以null结尾的字符串,因此标准不会将其标记为
noexcept

rational的定义如下:

标记为
noexcept
的函数很难测试 当函数标记为
noexcept
时,就无法标记测试失败, 特别是在测试驱动程序中,通过抛出异常。一个常见的例子是代码 在进入函数时验证先决条件的:

T& std::vector<T>::front() noexcept {
 assert(!this->empty());
 return *this->data();
}
T&std::vector::front()无例外{
断言(!this->empty());
返回*此->数据();
}
当验证来自测试驱动程序的此类防御检查时,一种合理的方法是 注册一个断言处理程序,该处理程序抛出一个定义良好的违反前提条件的异常, 测试驱动程序捕捉到的,以确保正确的
断言
s确实处于 地点

现在我们可能会认为,当
向量
为
空,是未定义的行为,因此我们不应期望任何保证。问题是库正在指定未定义的行为;对于编译器来说,这段代码是
定义良好,如果
assert
抛出异常,程序必须终止 以明确规定的方式挫败测试驾驶员

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


顺便说一下,由于:

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


libstdc++
libc++
可以自由标记这个重载
noexcept

老实说,我不知道为什么这个问题会得到这么多的赞成票
Clang
的格式为:
int-compare(const-value\u-type*\u-s)const-NOEXCEPTGCC也是如此:
int compare(const\u CharT*\u s)const\u GLIBCXX\u NOEXCEPT
看起来取决于实现,但从逻辑上看,它应该是
noexcept
。我想我们需要一个语言律师来获得真正的答案……但我假设,标准不要求
std::string
将字符串存储为
图表*
,以便允许小字符串优化。然而,这也意味着我们可能需要进行一些转换,以实现实际的
比较。此转换可能需要分配内存,内存可能会耗尽,因此可能会抛出。因此,标准无法从实现中强制执行
noexcept
,尽管在实践中它们仍然可能是
noexcept