[英]std:string::substr is exception safe?
I wrote some code where I use substr
from std::string
. 我在std::string
使用substr
编写了一些代码。
According to this C++ documentation : 根据此C ++文档 :
If pos is greater than the string length, an out_of_range exception is thrown. 如果pos大于字符串长度,则抛出out_of_range异常。
As I already checked, if I execute this function with following parameters: 正如我已经检查过的,如果我使用以下参数执行此功能:
I execute function: test.substr(0,test.size()-2);
我执行功能: test.substr(0,test.size()-2);
std::string test = {"ABC"}; result: test == "A"
std::string test = {"AB"}; result: test == ""
std::string test = {"A"}; result: test == "A"
std::string test = {""}; result: test == ""
My conclusions are: 我的结论是:
My question: 我的问题:
Is it safe to leave it as test.substr(0,test.size()-2);
将其保留为test.substr(0,test.size()-2);
是否安全test.substr(0,test.size()-2);
without checking its size before? 之前没有检查它的大小?
This is completely safe. 这是完全安全的。 It is only the first parameter that matters if an exception is thrown (besides a bad_alloc
for running out of memory but you have other problems then). 如果引发异常,它只是第一个参数(除了bad_alloc
耗尽内存,然后还有其他问题)。
The first parameter must be in [0, size()]
. 第一个参数必须位于[0, size()]
。 Since you use 0
, and 0
is always in [0, size()]
, you'll never throw a std::out_of_range
exception. 由于您使用0
,并且0
始终位于[0, size()]
,因此永远不会引发std::out_of_range
异常。
What happens if the second parameter is greater than the sub string size could be is that you just get the full sub string. 如果第二个参数大于子字符串的大小,会发生什么,就是您只得到完整的子字符串。 So test.substr(0,test.size()-2);
所以test.substr(0,test.size()-2);
for std::string test = {""}
will always result in ""
since test.size()-2
is a really big number (unsigned underflow). 对于std::string test = {""}
总是会导致""
因为test.size()-2
是一个非常大的数字(无符号下溢)。
The function throws an exception when pos > size()
As in your examples the parameter pos
is always equal to 0 then the function is safe. 当pos > size()
时,该函数引发异常。在您的示例中,参数pos
始终等于0,那么该函数是安全的。 That is the pos
never can be greater than the value of size()
. 那就是pos
永远不能大于size()
的值。
Take into account that the second parameter is defined like 考虑到第二个参数的定义如下
basic_string substr(size_type pos = 0, size_type n = npos) const;
^^^^^^^^^^^^^^^^^^
and the function (C++ Standard ) behaves like 并且函数(C ++ Standard)的行为类似于
2 Effects: Determines the effective length rlen of the string to copy as the smaller of n and size() - pos. 2效果:确定要复制的字符串的有效长度rlen为n和size()-pos中的较小者。
For this expression 对于这个表达
test.size()-2
that has an unsigned integer type when size()
is less than 2 when you have a big unsigned value (due to the usual arithmetic conversions). 当您有较大的无符号值时(由于通常的算术转换),当size()
小于2时,它具有无符号整数类型。 For example 例如
#include <iostream>
#include <string>
int main()
{
std::string s;
auto n = s.size() - 2;
std::cout << n << '\n';
return 0;
}
the program output is 程序输出为
18446744073709551614
So the function selects the value of the member function size()
. 因此,该函数选择成员函数size()
。
This situation is demonstrated by these two examples 这两个例子说明了这种情况。
4)std::string test = {"A"}; result: test == "A"
5)std::string test = {""}; result: test == ""
Yes, it is safe, but not for reasons you think it is. 是的,它是安全的,但并非出于您认为是安全的原因。
First things first: std::string::substr
is not fully exception safe, it will throw if pos
(ie first argument) is greater than size()
. 首先要注意的是: std::string::substr
不是完全异常安全的,如果pos
(即第一个参数)大于size()
,它将抛出异常。
Secondly, both arguments to substr
are of type std::string::size_type
, which is by default an unsigned integral type. 其次, substr
两个参数均为std::string::size_type
类型,默认情况下为无符号整数类型。
Because it is unsigned, underflow is well-defined, so 0 - 2
is going to result in std::numeric_limits<std::string::size_type>::max() - 1
. 因为它是无符号的,所以下溢是定义明确的,因此0 - 2
将导致std::numeric_limits<std::string::size_type>::max() - 1
。
There is no upper bound on second argument to substr()
, so it is safe to call it with as high value as you wish (in fact, default argument is likely std::numeric_limits<std::string::size_type>::max()
). substr()
第二个参数没有上限,因此可以安全地调用substr()
高的值(实际上,默认参数可能是std::numeric_limits<std::string::size_type>::max()
)。
So, what happens when you call substr(0, negative_value)
is you ask "give me substring from index 0
to huge_number
", which in probably all cases will return you the whole string. 所以,当你调用发生substr(0, negative_value)
是你问“给我从指数串0
至huge_number
”,这大概在所有的情况下将返回整个字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.