C++,这个goto语句是否合理?

Any*_*orn 9 c++ exception-handling goto

我稍微改变了标题因为我认为这是更合适的问题.

你会重构它(似乎合法使用goto)?如果,您将如何重构以下代码以删除转到语句?

if (data.device) {
    try {
        ...
    }
    catch(const std::exception&) { goto done; }
    ... // more things which should not be caught
done: ;
}
Run Code Online (Sandbox Code Playgroud)

完整的声明

#ifdef HAVE_GPU
            // attempt to use GPU device
            if (data.device) {
                try {
                    Integral::Gpu eri(S, R, Q, block.shell());
                    eri(basis.centers(), quartets, data.device);
                }
                // if GPU fails, propagate to cpu
                catch(std::exception) { goto done; }
                data.device += size;
                host_index.extend(block_index);
                block_index.data.clear();
            done: ;
            }
#endif
Run Code Online (Sandbox Code Playgroud)

谢谢

在看过大多数人的偏好之后,我决定带着旗帜,但是约克先生发表评论.

谢谢大家

Ama*_*9MF 15

if (data.device)
{
    bool status = true;

    try
    {
        ...
    }
    catch(std::exception)
    {
        status = false;
    }

    if (status)
    {
    ... // more things which should not be caught
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么人们坚持引入新的变量和分支只是为了避免转到?停止喝"考虑有害"论文的kool援助(更好的是,实际上阅读了论文,你会看到Dijkstra不会保存从不使用它们)并且实际上对你正在做的事情进行了一些批判性思考.您已经为代码添加了更多状态和更多分支,以满足"我没有使用`goto`." (5认同)

小智 8

第一:goto本身并不邪恶.为了在代码中没有字母"goto"的纯粹重构而进行重构是无稽之谈.将它重构为能够完成与goto相同的事情的东西很好.将糟糕的设计改为更好的设计并且不需要goto或替换它也很好.

话虽如此,我会说你的代码看起来与最终发明的代码完全一样.太可悲了C++没有这样的东西......所以也许最简单的解决办法就是保持这样.

  • 不幸的是finally()在这里不是正确的解决方案,因为代码仅在没有异常时使用,最后另一方面意味着它应该总是被执行(即使存在异常).虽然C#和Java等语言最终需要它,但C++不需要它,因为有更好的技术来实现同样的东西.虽然我同意你的所有其他观点.不要修复未破坏的东西. (4认同)

Jam*_*lis 7

您可以捕获异常并重新抛出可以在条件块之外处理的特定异常.

// obviously you would want to name this appropriately...
struct specific_exception : std::exception { };

try {
    if (data.device) {
        try {
            // ...
        }
        catch(const std::exception&) { 
            throw specific_exception(); 
        }

        // ... more things which should not be caught ...
    }
}
catch (const specific_exception&) { 
    // handle exception
}
Run Code Online (Sandbox Code Playgroud)