特别考虑C ++ string
类构造函数规范,我们有:
string (const string& str, size_t pos, size_t len = npos);
string (const char* s, size_t n);
除了字符串与c-string之外,它们基本上具有相同的形式/意图。但异常规范却截然不同:
如果pos大于str的长度,则out_of_range异常为 抛出。
如果n大于s指向的数组,则会导致 未定义的行为。
我想知道为什么会这样?除了性能之外,什么时候抛出异常与允许"未定义的行为?#34 ;?答案似乎取决于以下内容:
答案 0 :(得分:3)
两种情况的不同之处仅在于,在第一种情况下,实现中可能检查传递的参数是否存在错误,而在第二种情况下< em>不可能(没有办法检查字符串的长度,因为只传递了一个指针)。
所以一般规则如下:
答案 1 :(得分:2)
库实现者必须实现C ++标准规定的行为,并且C ++标准指定:
basic_string(const basic_string& str,
size_type pos, size_type n = npos,
const Allocator& a = Allocator());
需要:pos&lt; = str.size()
抛出:out_of_range如果pos&gt; str.size()。
在
的情况下basic_string(const charT* s, size_type n,
const Allocator& a = Allocator());
标准只是说:
要求:s指向至少n个charT元素的数组。
(全部来自§21.4.2[string.cons])
由于标准没有规定在第二种情况下发生的情况如果不满足要求,那就是未定义的行为,让库实现自由地做它想做的任何事情。但是,库无法实际检测到未满足要求的事实,因此可以自由地假设满足要求,然后让程序以硬件对读取无效地址的任何反应中断。
如果您正在寻求理由,您应该寻求标准的理由。图书馆实施者几乎没有灵活性。
答案 2 :(得分:1)
您示例中的行为原因非常明显。