gpt4 book ai didi

c++ - 如何在不抛出的情况下构造 异常?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:37:06 30 4
gpt4 key购买 nike

<stdexcept> 中定义的异常(例如 std::logic_errorstd::runtime_error 及其子类,例如 std::system_error )具有需要字符串参数的构造函数,例如:

domain_error(const string& what_arg);
domain_error(const char* what_arg);

有后置条件

strcmp(what(), what_arg.c_str()) == 0
strcmp(what(), what_arg) == 0

分别。没有要求传递给构造函数的这些参数在这些异常的生命周期内保持有效,因此确保后置条件成立的唯一方法是复制并存储这些动态字符串。这需要内存,所以我假设他们的构造本身可能会抛出 std::bad_alloc或类似情况,这通常是最意想不到的。这会导致问题,因为我在野外看到的每个代码示例都鼓励人们编写如下代码

if (haveError)
throw std::runtime_error("BOO!"); // May throw std::bad_alloc instead?!

而在其他地方预先构造异常似乎更安全,例如:

struct A {
// During allocation of A one would often expect std::bad_alloc anyway:
A() : m_someException("BOO!") {}
void f() {
/* Do stuff */
if (haveError)
throw m_someException;
/* Note that according to §18.8.1.2 all standard library
classes deriving from `std::exception` must have publicly
accessible copy constructors and copy assignment operators
that do not exit with an exception. In implementations such
exception instances most likely share the common string
with all their copies. */
}
std::runtime_error const m_someException;
};

这让我对抛出任何此类异常的库非常谨慎,例如 regex_error来自 <regex>在 C++11 中!!!

为什么这些异常没有 no-throw/noexcept 构造函数?C++ 核心指南对此有发言权吗?

PS:我个人会离开 what()异常祖先链中此时的纯抽象方法。

编辑 09.10.2017:这是一个证明 std::runtime_error 的 PoC建筑可以扔一个std::bad_alloc相反:

#include <cstddef>
#include <cstdlib>
#include <new>
#include <stdexcept>
#include <string>

bool throwOnAllocate = false;

void * operator new(std::size_t size) {
if (!throwOnAllocate)
if (void * const r = std::malloc(size))
return r;
throw std::bad_alloc();
}

void operator delete(void * ptr) { std::free(ptr); }

int main() {
std::string const errorMessage("OH NOEZ! =(");
throwOnAllocate = true;
throw std::runtime_error(errorMessage);
}

最佳答案

简短的回答,不可能绝对保证没有异常(exception)地构造任何对象。

您可以考虑在堆栈上进行分配,但您的线程堆栈可能会用完并导致系统错误/异常。你的 CPU 可能会收到一个外部中断,就在你抛出时,那个系统无法处理,一切都被炸毁了。正如其他人所建议的那样,不要为小事烦恼。内存不足是大多数用户程序无法恢复的,所以不用担心,优雅地失败。不要试图处理每一个糟糕的情况,只处理那些您可以轻松恢复的情况。

作为旁注,对于内存不足的情况,许多高画质游戏会在游戏初始化期间预先进行所有堆分配,并尽量避免在游戏开始后出现内存不足的问题游戏过程中内存不足/分配缓慢(紧张的游戏和糟糕的用户体验)。同样,您可以巧妙地设计程序,以减少遇到糟糕情况的可能性。

关于c++ - 如何在不抛出的情况下构造 <stdexcept> 或 <system_error> 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36106747/

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