【问题标题】:Do function try blocks on non-contructor functions have any disadvantage?非构造函数上的函数 try 块有什么缺点吗?
【发布时间】:2023-03-19 00:30:01
【问题描述】:

函数try块是函数体的一种特殊形式,例如:

int f() try {
  // function body
} 
catch {
  // one or more catch-clauses.
}

主要用途是在构造函数中使用,以便记录任何基类的构造函数抛出的异常。但是,也允许在常规函数中使用它们。

在这方面存在一些(相当老的)问题,询问我们为什么需要它用于常规功能,例如Function try blocks, but not in constructors。但是,我的问题更多的是在另一个方向上:我可以在常规函数中使用它来替代常规的 try-block 而不用担心吗?比方说,只是出于审美原因?

我为 C++ 库开发了一个 C 接口,需要用 try 块封装每个接口函数以捕获任何异常。因此,我想避免在每个函数中使用额外的大括号块......

只有一件事引起了我的担忧:在答案https://stackoverflow.com/a/11535436/6695750 中,davka 引用了 2000 年的一篇文章,声称您不能从对应于函数尝试块的捕获块返回值。我用 gcc 5.4.0 进行了测试,在那里我可以毫无问题地从 catch-block 返回一个值。这是标准,还是 gcc 的非标准扩展?

【问题讨论】:

  • 我没有看到任何陷阱,除了构造函数/析构函数会重新抛出。
  • second answer you're quoting 完全是错误的(在创建时就已经如此)。
  • 一个(小)陷阱是它出乎意料。如果您保持代码简单(C 层只调用 C++ 层并处理异常),那很好。如果您的代码随着时间的推移变得更加复杂/复杂(就像我的一些人所做的那样:))这可能会在这些年来变得很麻烦 - 那么您最好使用异常处理函数并将您的 C++ 代码作为访问者传递给它/ lambdas。

标签: c++ c++11 exception-handling function-try-block


【解决方案1】:

我可以在常规函数中使用它来代替常规 try-block 而不用担心吗?

在某些情况下您不能使用function-try-block:您不能访问catch 子句中的任何局部变量。

void g() {
    int i = 2;
    try {
        throw 2.3;
    } catch (double d) {
        cout << i << endl;   // OK. you can access i
        cout << d << endl;
    }
}

void f() try {
    int i = 2;
    throw 2.3;
} catch (double d) {
    cout << i << endl;   // FAIL! i is out of scope, you CANNOT access it.
    cout << d << endl;
}

【讨论】:

  • 是的,当然。在 g() 中,try-block 并不包含整个函数体,因此很明显,它不等同于 function-try-block。
【解决方案2】:
int f() try {
  // function body
} 
catch (/*..*/){
  // one or more catch-clauses.
}

等价于

int f() {
    try {
      // function body
    } 
    catch (/*..*/){
      // one or more catch-clauses.
    }
}

用于常规功能。

只有构造函数/析构函数有特殊处理,因为 catch 块抛出异常(隐式或显式)。

另见the docu here

【讨论】:

  • 这是有道理的。您能否提供标准或在线文档的参考资料?
猜你喜欢
  • 2011-02-27
  • 2011-08-07
  • 1970-01-01
  • 2019-12-27
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
  • 1970-01-01
  • 2011-08-02
相关资源
最近更新 更多