【问题标题】:custom (non-exception) error handling strategy in c++c++ 中的自定义(非异常)错误处理策略
【发布时间】:2011-05-08 06:26:17
【问题描述】:

出于 X 或 Y 的原因,人们在必要时在 C++ 中使用哪些错误处理方案来避免异常?我已经实施了自己的策略,但我想知道其他人的想法,并就每种方法的优缺点进行讨论

现在,为了解释我在特定项目中使用的方案,可以这样总结。通常需要抛出的方法,实现如下接口:

bool methodName( ...parameters.... , ErrorStack& errStack)
{
   if (someError) { errStack.frames.push_back( ErrorFrame( ErrorType , ErrorSource ) );
   return false;
   }
   ... normal processing ...
   return true;
}

简而言之,返回参数表示处理是否正常或发生错误。错误堆栈基本上是包含错误详细信息的错误帧的 std::vector:

enum ErrorCondition {
            OK,
            StackOverflowInminent,
            IndexOutOfBounds,
            OutOfMemory
        };


        struct ErrorFrame {
            ErrorCondition condition;
            std::string source;

            ErrorFrame( ErrorCondition cnd , const char* src ) : condition(cnd) , source(src) {}

            inline bool isOK() const {
                return OK == condition;
            }
        };

        struct ErrorStack {
            std::vector< ErrorFrame > frames;

            void clear() {
                frames.clear();
            }
        };

这种方法的优点是详细的错误堆栈,类似于 java 异常给出的错误,但没有异常的运行时开销。主要缺点是(除了非标准性之外,我仍然必须以某种方式处理来自第三方代码的异常并转换为 ErrorCondition),这是难以维护 ErrorCondition 枚举,因为源库的多个组件需要不同的错误,因此该策略的第二个版本可以为 errorConditions 使用某种继承层次结构,但我仍然对实现它的最佳方法没有信心

【问题讨论】:

  • “这种方法的优点是详细的错误堆栈,类似于 java 异常给出的错误,但没有异常的运行时开销。”您确实意识到使用异常的“运行时开销”与维护此堆栈的成本相比是微不足道的,对吧?
  • 也许我错过了你的观点,但我的理解是,即使没有抛出异常,异常处理也会产生运行时成本。在这种情况下,没有错误时唯一的额外成本是在每个相关函数上传递额外的引用
  • 在您的实现中存在大量开销,因为必须检查每个函数是否通过或失败。
  • 由于您使用的是标准库 stringvector,因此您已经在使用异常,因为标准库分配器必须使用异常来传达分配错误。
  • 绝大多数异常处理开销仅在抛出异常时才会产生。在正常操作期间,开销小于您在此处执行的操作。 “我们应该忘记小的效率,比如大约 97% 的时间:过早的优化是万恶之源”——Knuth

标签: c++ exception-handling error-handling stack-trace


【解决方案1】:

【讨论】:

  • 讨论异常处理而不是替代错误处理策略(尽管它确实简要列出了替代方案)。
猜你喜欢
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
  • 2021-04-27
  • 2016-02-14
  • 1970-01-01
相关资源
最近更新 更多