c++ - 允许编译器优化异常抛出吗?

标签 c++ exception compiler-construction compiler-optimization

我们今天在工作中一直在讨论这个话题,我们谁也无法对这个问题给出明确的答案。考虑以下情况:

int foo()
{
  int err;

  err = some_call(1);

  if (err != 0)
    return err;

  err = some_call(2);

  if (err != 0)
    return err;

  err = some_call(3);

  if (err != 0)
    return err;

  err = some_call(4);

  if (err != 0)
    return err;

  bar();

  return err;
}

有很多代码重复。显然,这可以用宏分解,遗憾的是不能用模板分解(因为 return 子句)。或者至少不是直接的。

现在的问题是,如果我们用异常替换那些返回错误代码,并立即捕获这些异常,编译器是否允许并且足够聪明以检测模式并完全避免抛出异常?

这是我的意思的说明:
int foo()
{
  try
  {
    // some_call now throws a ErrorReturned exception that contains the error code upon failure.
    some_call(1);
    some_call(2);
    some_call(3);
    some_call(4);
  }
  catch (ErrorReturned& ex)
  {
    return ex.error_code();
  }

  bar();

  return 0;
}

现在,没有当前的性能问题,所以是的,我们不需要优化甚至关心它。这更多地是为了了解允许编译器做什么。

简而言之,这是一种“好”的做法吗?如果是这样,编译器可以通过不抛出异常来优化它吗? (假设异常构造没有副作用)

最佳答案

“编译器足够聪明吗”似乎暗示异常在您的项目中没有任何用途,如果是这种情况,您不应该首先使用它们(当然,除非您实际上有可能获得异常)。

简短回答:不,编译器不会根据您使用它们的模式删除您的异常/异常处理。

当你使用 try/catch 时,它处理的异常被添加到主异常表中;该表可以被监视、连接、添加和删除。仅仅因为您立即捕获异常并不意味着其他事情也不会发生。

边源 :
一篇论文写在 Optimizing Away C++ Exception Handling 它概述了与异常有关的所有(几乎所有)当前优化实现。在整个过程中,它表明目前它们没有在编译时被剥离,而是对它们进行了优化。该论文本身建议增强 EH(异常处理)以消除不必要的异常,总体而言,这是一本很好的读物。

更新 (其他来源)
进一步研究该主题,GCC 编译器似乎没有优化掉异常;但是,它确实提供了这样做的选项: -fno-exceptions .此选项将删除所有异常并直接将其替换为 abort()来电。

另一个来源( here on StackOverflow )没有直接提到“删除异常”,但确实概述了对异常进行的两个优化,setjmp/longjmp和零成本。可以通过突出显示实际增强而不提及“完全消除异常”来推断没有这种优化(但是,至少对于提到的编译器)。可以找到有关这些优化的更详细信息的另一个来源 here .

关于c++ - 允许编译器优化异常抛出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64525555/

相关文章:

delphi - 使用 Set8087CW、SetMXCSR 和 TWebBrowser 屏蔽浮点异常

c - Linux内核如何编译自己?

java - 是否有生成 DSL 解析器的工具不需要生成的解析器运行时?

c++ - directshow中的CSource和CSourceStream有什么区别?

java - 抛出错误的异常

c# - 如何处理未经检查的异常?

C# 编译器错误地优化了代码

c++ - 为什么这不要求用户进行其他输入?

c++ - 返回对对象 vector 的 const 引用

C++ std::enable_if