是否可以使用catch语句中的“转到”

时间:2011-03-17 15:32:35

标签: c++ try-catch goto

我曾经被告知过的一切都是邪恶的,远离他们,但我认为他们可以帮助我(?)。我想为用户提供一个选项,以便在发现异常时重新启动应用程序,并且在我的工作中遇到一些麻烦......

我的应用程序将由另一个进程监视,但有一些例外,我希望用户能够在不将控制返回给调用进程的情况下决定该做什么。

这样的东西“可以接受”吗?还有其他建议吗?

非常感谢!

int main(){

    initialize:
       try{
        //do things
       }
       catch(...)
       {
          cout<<"Would you like to try initializing again?"<<endl;

          //if yes
            goto initialize;

          //if not
          abort(); //or something...
        }

return 0;
}

6 个答案:

答案 0 :(得分:8)

为什么不喜欢这个?

while(true){
  //Do stuff
  if(exit){
    break;
  }
}

continue = true;
do{
  //Do stuff
  if(exit){
    continue = false;
  }
}while(continue);

答案 1 :(得分:6)

你可以尝试:

int main()
{
     while(true)
     {
          try
          {
               program();
          }
          catch(std::exception& e)
          {
               std::cout << "Start again?" << std::endl;
               //Check ...
               if(!go_on)
                    break;
          }
     }
     return 0;
}

答案 2 :(得分:5)

goto

顺便说一句,break之外的switch也是如此。 continue关键字稍微不受谴责,因为至少它会尊重封闭循环的条件。

在正确的地方捕捉异常非常重要 - 您可以最有效地处理这种情况。

如果一个条件变得不方便(就像我的情况中的“再试一次?”),考虑否定它(“失败?”)以获得更清洁的结构。

// Tries until successful, or user interaction demands failure.
bool initialize() {
    for ( ;; ) {
        try {
            // init code
            return true;
        }
        catch ( ... ) {
            cout << "Init Failed. Fail Program?" << endl;
            if ( yes ) {
                return false;
            }
        }
    }
}

int main() {
    if ( ! initialize() ) {
        return EXIT_FAILURE;
    }
    // rest of program
    return EXIT_SUCCESS;
}

注意:这不使用gotobreak,并且不会递归(尤其不在{{1}内})。

答案 3 :(得分:4)

是的,从技术上讲它是可以的,但通常会“考虑有害”的考虑因素。

答案 4 :(得分:2)

最初的引用是(我相信)“不受控制地使用goto被视为有害”。 Gotos可能很有用,但必须以受控方式使用。有一种编程技术,用于创建依赖于程序或数据状态的可重入子程序,这些子程序肯定需要定向跳转。虽然这种技术可能被认为是老式的,但我知道它仍然被使用,但是被更现代的语言和编译器功能所隐藏。控制的关键在于你必须停下来问问自己,不仅仅是“是否有一种更有条理的方式来做同样的事情” - @Justin - 而且“在什么具体条件下我会使用goto?”如果没有这个更广泛的答案,方便可能不是使用它的充分条件。

答案 5 :(得分:1)

处理异常的正常方法是在你可以做某事的地方。很明显,你试图处理它们的地方是不对的,因为你必须使用goto。

所以,像这样:

void mainLoop() // get user settings, process, etc
{
   try
   {
     // 1) get user settings
     // 2) process data
     // 3) inform of the result
   }
   catch( const exception_type & e)
   {
     // inform of the error
   }      
}

int main()
{
  try
  {
    while(true)
      mainLoop();
  }
  catch(...)
  {
    std::cout<<"an unknown exception caught... aborting() " << std::endl;
  }
}