1. 程式人生 > 其它 >[C/C++] 幾種錯誤處理的方式

[C/C++] 幾種錯誤處理的方式

  1. goto 跳轉集中處理

    int func()
    {
        if(!try_do_a()) goto END_FUNC;
        if(!try_do_b()) goto END_FUNC;
        // ...
        return 0;
    END_FUNC:
        // do something
    }
    
  2. do{...}while(0) (原理同上, 其實就是 goto 的另一種形式)

    int func()
    {
        int r = 0;
        do
        {
            if(!try_do_a()) { r = ...; break; }
            if(!try_do_b()) { r = ...; break; }
            // ...
        }while(0);
        if(r != 0)
        {
            // do something
        }
        else return 0;
    }
    

    1. & 2. 適用於大部分錯誤, 可以告知呼叫者具體錯誤.

  3. 利用 throwtry{...}catch(...){...}

    int func()
    {
        if(!try_do_a()) throw some_error_data;
        if(!try_do_b()) throw some_error_data;
        // ...
        return 0;
    }
    int caller()
    {
        try
        {
            func();
        }
        catch(error_data_type& e)
        {
            // do something
        }
    }
    

    適用於出現重大且不可恢復的錯誤.

  4. 利用 C++ RAII 機制在變數析構時處理 (在 C++11 之後配合 lambda 更加方便)

    class __scope_error
    {
    public:
        explicit __scope_error(std::function<void()> in_on_exit)
            : m_on_exit(in_on_exit), m_is_noerror(false) {}
        ~__scope_error() { if (!m_is_noerror) m_on_exit(); }
    
        __scope_error(const __scope_error&) = delete;
        __scope_error& operator=(const __scope_error&) = delete;
    
        void ok() { m_is_noerror = true; }
    private:
        std::function<void()> m_on_exit;
        bool m_is_noerror;
    };
    
    int func()
    {
        __scope_error se(a_func);
        if(!try_do_a()) return -1;
        if(!try_do_b()) return -1;
        // ...
        se.ok();
        return 0;
    }
    

    適用於絕大多數錯誤, 推薦使用.