Можно ли использовать «go to» из оператора catch - PullRequest
6 голосов
/ 17 марта 2011

Все, что мне когда-либо говорили, это то, что идти к злу и держаться от них подальше, но я думаю, что они могут помочь мне здесь (?).Я хотел бы предоставить пользователю возможность перезапустить приложение, когда возникнет исключение, и у меня возникли некоторые проблемы, связанные с тем, что делать ...

Мое приложение будет отслеживаться другим процессом,но есть некоторые исключения, когда я хочу, чтобы пользователь мог решать, что делать, не возвращая управление вызывающему процессу.

Является ли что-то подобное "приемлемым"?Любые другие предложения?

Большое спасибо!

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 ]

8 голосов
/ 17 марта 2011

Почему бы не так?

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

или

continue = true;
do{
  //Do stuff
  if(exit){
    continue = false;
  }
}while(continue);
6 голосов
/ 17 марта 2011

вы можете попробовать:

int main()
{
     while(true)
     {
          try
          {
               program();
          }
          catch(std::exception& e)
          {
               std::cout << "Start again?" << std::endl;
               //Check ...
               if(!go_on)
                    break;
          }
     }
     return 0;
}
5 голосов
/ 17 марта 2011

A goto можно всегда избегать, давая код уборщика.

Кстати, то же самое относится и к break s вне 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;
}

Примечания: Это не использует goto или break и не повторяется ( особенно не из блока catch).

4 голосов
/ 17 марта 2011

Да, технически это нормально, но применимы обычные "опасные"

2 голосов
/ 17 марта 2011

Первоначальная цитата была (я считаю) "неконтролируемым использованием goto, считающимся вредным". Gotos может быть полезен, но должен использоваться контролируемым образом. Существует один метод программирования, позволяющий создавать входящие подпрограммы, зависящие от состояния программы или данных, что положительно требует направленных переходов. Хотя эту технику вполне можно считать старомодной, я понимаю, что она все еще используется, но скрыта под более современным языком и возможностями компилятора. Суть контроля заключается в том, что вы должны остановиться и спросить себя, не только «существует ли более структурированный способ сделать то же самое» - @Justin - но также «при каких конкретных условиях я буду использовать goto?» Быть удобным, вероятно, не является достаточным условием, чтобы использовать его без этого более широкого ответа.

1 голос
/ 17 марта 2011

Обычный способ обработки исключений - это то место, где вы можете что-то сделать.Очевидно, что место, где вы пытаетесь с ними справиться, не подходит, так как вы должны использовать 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;
  }
}
...