Подтвердить что ты не робот

В чем преимущество do-while (false)?

При просмотре кода, который был обработан другим сотрудником, я вижу много кода, написанного на:

do{
    ...
}while(false);

Какое преимущество (если таковое имеется) предоставляет?

Вот более скелет, который происходит в коде:

try{
    do{
        // Set some variables

        for(...) {
            if(...) break;
            // Do some more stuff
            if(...) break;
            // Do some more stuff
        }
    }while(false);
}catch(Exception e) { 
    // Exception handling 
}

Update:

Версия С++:
Обходные циклы do-while-false?

4b9b3361

Ответ 1

Возможно, это было сделано, чтобы в любой момент выскочить из цикла, например:

do
{
    ...
    if (somethingIsWrong) break;
    //more code
    ...
}
while(false);

Но, как говорили другие, я бы так не сделал.

Ответ 2

В Java нет причин для этого.

В C это общая идиома при определении макросов:

Рассмотрим:

#define macro1 doStuff(); doOtherStuff()
#define macro2 do{ doStuff(); doOtherStuff(); } while( false )

if( something ) macro1; // only the first statement in macro1 is executed conditionally
if( something ) macro2; // does what it looks like it does

... но макросы в C являются злыми, и их следует избегать, если это вообще возможно.

Является ли ваш коллега из C фона?

Ответ 3

Нет преимуществ. Не делайте этого.

Ответ 4

Его можно использовать, чтобы перейти к концу блока, который можно использовать, чтобы избежать вложения вложенных блоков if/then.

do {
    if (done()) continue;
    // do a bunch of stuff
    if (done()) continue;
    // do a bunch more stuff
    if (done()) continue;
    // do even more stuff
} while (false);

Ответ 5

Это используется в C, чтобы определить макрос внутри блока. См. этот, например.

Пример: недопустимо следующее:

#define f(x) { g(x); h(x); }

if (x >= 0) f(x); else f(-x);

но с этим определением он будет работать:

#define f(x) do { g(x); h(x) } while(false)

Ответ 6

Это бесполезно, но кодер мог использовать команды множественного разрыва, чтобы выполнить некоторую странную обработку исключений.

do{
if(<something>){...}else{break}
if(<something else>){...}else{break}
...
}while(false)

Предоставлено его глупо, но я нашел что-то вроде старой программы c однажды

Ответ 7

Ваша интуиция правильная. Это совершенно бесполезная вещь.

Возможно, что кто-то, кто его закодировал, имел в качестве условия не что иное, как false, а просто изменил его на false, а не удалил весь блок, чтобы не потерять эту "историю" кода. Тем не менее, это просто держится за соломинку. Чтобы быть откровенным, это просто простой пример tautology, который не имеет места в коде.

Ответ 8

В почти любом другом языке, кроме C/С++, это не дает тактического преимущества.

В C/С++ есть случай с макросами, где do/while (false) облегчает безопасное развертывание макроса во множество операторов. Это выгодно, когда макрос в противном случае выглядит как обычный вызов функции.

Ответ 9

Посмотрите на question

ОП спрашивает об этой точной конструкции и объясняет некоторые причины ее использования. Похоже, консенсус заключается в том, что это плохо.

Ответ 10

В качестве места для будущего, когда вместо false ставится другое условие.

Ответ 11

Он может использоваться для пропуска выполнения какого-либо кода (например, goto или что-то еще), но когда я снова смотрю на него, кажется, что существует цикл for (где операторы if(...) break;) в do-while. В противном случае я бы сказал, что это будет Java-версия goto...

Ответ 12

Я использовал это соглашение годами! Это наиболее полезно, когда у вас есть "конвейер" обработки и/или условных проверок. Он просто избегает нескольких уровней вложенных операторов if() и, таким образом, делает код (намного) более простым для чтения. Да, есть альтернативы, такие как try/catch, и я использую этот стиль только в определенных ситуациях с тонким/нижним уровнем.

Я начинаю "цикл" (никогда не циклы) с комментарием вроде...

// Error loop (never loops)

Цикл ошибок...

set errorCode = fail;
do {
  if (this)
    break;

  if (that)
    break;

  // Success
  set errorCode = ok;

  // Alternative Success
  errorCode = doWhatever();
} while (false);

Рассмотрим этот стиль, если у вас есть куча вложенных операторов if(), а ваши отступы - более трех уровней.

Я использовал это соглашение в Perl, C/С++, Java и Delphi/Pascal.

Ответ 13

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

Ответ 14

Единственная причина, по которой я могу думать, - создать блок, чтобы сделать переменные, объявленные в {...} более жесткими, но есть более эффективные способы сделать это (например, создание функций или просто создание блоков - наконечник шляпы Пете Кирхэй).