gpt4 book ai didi

C++11 引入了采用 `const char*` 的异常构造函数。但为什么?

转载 作者:IT老高 更新时间:2023-10-28 12:43:40 25 4
gpt4 key购买 nike

Standard library defect #254其中包括添加新的异常构造函数:

std::logic_error::logic_error(const char* what_arg);
std::runtime_error::runtime_error(const char* what_arg);
// etc.

给出了这样一种想法,即存储 std::string 会打开一些与潜在的内存分配问题有关的蠕虫。

但是,following initiation of a discussion by orlp in the Lounge ,令我震惊的是,除非标准要求 what_arg 只是一个字符串文字(或指向其他静态存储持续时间缓冲区的指针),否则它必须执行 C 的拷贝-string 无论如何都是为了保持成员函数 what().

的明确定义

那是因为:

void bar() {
char buf[] = "lol";
throw std::runtime_error(buf);
}

void foo() {
try {
bar();
}
catch (std::exception& e) {
std::cout << e.what() << '\n'; // e.what() points to destroyed data!
}
}

但我看不到任何这样的授权。事实上,异常对象是否深拷贝 what_arg 似乎是完全不确定的。

如果他们这样做,那么首先添加重载(消除额外分配)的大部分理由似乎完全是空洞的。

这可能是一个标准缺陷,还是我在这里遗漏了什么?
这只是“程序员:不要在任何地方传递悬空指针”的情况吗?

最佳答案

这允许(或至少显然是为了促进——见下文)实现在它可以检测到(通过本身不是标准化的方式)传递的是字符串文字或其他东西的情况下消除拷贝else 具有静态存储持续时间。

例如,假设编译器将所有字符串文字汇集到由 __string_literals_begin__string_literals_end 分隔的范围内。然后在 std::exception 的构造函数内部的某个地方,它可能具有以下一般顺序的代码:

namespace std {
exception::exception(char const *s) {
if (in_range(s, __string_literals_begin, __string_literals_end)) {
stored_what = s;
destroy_stored_what = false;
}
else {
stored_what = dupe(s);
destroy_stored_what = true;
}
// ...
}

exception::~exception() {
if (destroy_stored_what)
delete_string(stored_what);
}

链接的 DR 中的最终评论指出:

[ Oxford: The proposed resolution simply addresses the issue of constructing the exception objects with const char* and string literals without the need to explicit include or construct a std::string. ]

因此,根据当时的评论,委员会意识到这些过载并不能满足所有需求,但确实解决了(至少被认为是)需求。

(几乎)可以肯定的是,即使没有标准强制要求,实现可以提供这些重载——尽管如此,委员会似乎已经相信添加它们是有用的,主要是(如果不是唯一的)对于上面概述的情况——当一个字符串文字被传递给ctor时只做一个浅拷贝。

关于C++11 引入了采用 `const char*` 的异常构造函数。但为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29052647/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com