在这个非常具体的案例中使用goto ......替代方案?

时间:2018-01-28 11:30:23

标签: c++ exception flags goto

我对在C ++代码中使用goto的可能性有疑问:我知道尽可能避免使用goto,但在这个特殊情况下,我遇到的困难很少找到避免使用多个嵌套if-else和/或其他二进制标志的好方法...... 代码如下所示(仅报告相关部分):

// ... do initializations, variable declarations, etc...

    while(some_flag) {
        some_flag=false;

        if(some_other_condition) {
            // ... do few operations (20 lines of code)

            return_flag=foo(input_args); // Function that can find an error, returning false
            if(!return_flag) {
                // Print error
                break; // jump out of the main while loop
            }

            // ... do other more complex operations
        }

        index=0;
        while(index<=SOME_VALUE) {
            // ... do few operations (about 10 lines of code)
            return_flag=foo(input_args); // Function that can find an error, returning false
            if(!return_flag) {
                goto end_here; // <- 'goto' statement
            }

            // ... do other more complex operations (including some if-else and the possibility to set some_flag to true or leave it to false
            // ... get a "value" to be compared with a saved one in order to decide whether to continue looping or not
            if(value<savedValue) {
                // Do other operations (about 20 lines of code)
                some_flag=true;
            }
            // ... handle 'index'
            it++; // Increse number of iterations
        }

        // ... when going out from the while loop, some other operations must be done, at the moment no matter the value of some_flag

        return_flag=foo(input_args);
        if(!return_flag) {
            goto end_here; // <- 'goto' statement
        }

        // ... other operations here
        // ... get a "value" to be compared with a saved one in order to decide whether to continue looping or not
        if(value<savedValue) {
            // Do other operations (about 20 lines of code)
            some_flag=true;
        }

        // Additional termination constraint
        if(it>MAX_ITERATIONS) {
            some_flag=false;
        }

        end_here:
        // The code after end_here checks for some_flag, and executes some operations that must always be done,
        // no matter if we arrive here due to 'goto' or due to normal execution.
    }
}

// ...

每次foo()返回false时,都不应执行更多操作,代码应尽快执行最终操作。另一个要求是,此代码(主要是while(index<=SOME_VALUE)内部的部分应尽可能快地运行,以尝试获得良好的整体性能。

正在使用'try / catch'块,其中try{}包含大量代码(实际上,函数foo()只有在调用时才能生成错误,这是在两个不同的点上仅限代码)可能的替代方案?在这种情况下使用不同的'try / catch'块会更好吗? 还有其他更好的选择吗?

提前多多感谢!

3 个答案:

答案 0 :(得分:1)

你能做到的一种方法是使用另一个虚拟循环和break这样的

 int state = FAIL_STATE;

 do {
     if(!operation()) {
         break;
     }

     if(!other_operation()) {
         break;
     }
     // ...
     state = OK_STATE;
 } while(false);

 // check for state here and do necessary cleanups

这样,您可以事先避免代码中的深层嵌套级别。

答案 1 :(得分:1)

三个明显的选择:

  1. 坚持goto

  2. 将清理代码与某些RAII类的析构函数关联。 (您可以将其写为std::unique_ptr作为lambda的删除。)

  3. 将您的功能重命名为foo_internal,并将其更改为return。然后在一个调用foo

  4. 的新foo_internal函数中编写清理

    所以:

    return_t foo(Args...) {
        const auto result = foo_internal(Args..);
        // cleanup
        return result;
    }
    

    通常,您的函数看起来太长,需要分解成更小的位。

答案 2 :(得分:1)

它是C ++!使用异常进行非本地跳转:

try {
    if(some_result() < threshold) throw false;
}
catch(bool) {
    handleErrors();
}
// Here follows mandatory cleanup for both sucsesses and failures