what() 不抛出异常(异常类)重要吗?

Is it important that what() does not throw (exception classes)?

C++ Primer 的练习要求

Why is it important that the what function [of exception classes] doesn’t throw?

由于无法检查我的回答,所以我希望得到意见。我认为在当前异常对象仍在处理时,在 catch 子句期间抛出另一个异常(而不是重新抛出 throw;)可能是一个错误(可能会调用 terminate)。似乎情况并非如此,完全可以抛出 catch 子句:

#include <iostream>

using namespace std;

int main(){


    try{
        try{
            throw exception();
        } catch(exception err){ throw exception();}
    } catch(exception err){ cout << "caught"} //compiles and runs fine, outputs "caught"


}

所以程序终止不用担心。看来,任何由 what() 抛出引起的问题至少应该可以由用户纠正,如果他们愿意的话。

也许那么,重要的可能是在处理错误时我们不希望发生更多意外错误? throws inside catch 子句主要用于将异常对象发送到调用链的更上游。用户可能会从他的程序深处收到一个错误,并且不想担心捕获到的错误必须与其自己的 try 块相关联。或者 what() 有自己的 throw 也可能导致递归效果(例如 what() 抛出异常,然后我们捕获这个异常并调用 what() 但是这然后抛出,等等)意味着它可能变得无法处理有什么错误吗? what() 可能会抛出多剧烈?

我认为没有什么不清楚的-正如您所描述的那样。如果异常 class 的 .what() 方法抛出错误,则整个 catch 的努力都被浪费了 :

try {
  someDangerousOperation();
}
catch(std::exception e) {
  // Ooops, instead of false,
  //we get another exception totally unrelated to original error
  someLogClassOrWhatever.save(e.what());
  return false;
}
return true;

想象一下,如果您要处理 what() 的异常,那会是多么疯狂的代码:

try {
  someDangerousOperation();
}
catch(std::exception e) {
  // Not very fun
  try {
    someLogClassOrWhatever.save(e.what());
  }
  catch(...) {
    alsoWhatHasFailedThatIsReallyGreat(); 
  }
  return false;
}

我觉得没什么了不起的,可能问题太简单了,看来一定有什么隐患。我觉得不是这样的。

想象一个非常好奇的编码员,有轻微的控制狂倾向(我自己认识其中几个),他真的很想知道他的程序出了什么问题,并用 [=25= 记录所有错误]()。所以他编码

try {
  code();
}
catch(std::exception &e) {
  std::cout<<e.what()
}

他对整个世界,尤其是对自己都非常满意。但现在他突然想到,e.what() 也可能抛出异常。所以他是代码:

try{
    try {
      code();
    }
    catch(std::exception &e) {
      std::cout<<e.what()
    }
}   
catch(std::exception &e) {
      std::cout<<e.what()
}

一分钟后他注意到,可能又出现了未捕获的异常!记住,他是个控制狂,所以他要写另一个 try-catch 块,然后再写一个又一个

所以你可以赌任何钱,他的项目会延迟——你怎么能这样对我的朋友?所以请确保 e.what() 不会抛出:)

我想这就是 what 是 noexcept 的原因。

std::exception::what() 不例外。因此,如果它抛出, std::terminate 就会被调用。是的,这很重要。