Ответ 1
Возможно, это было сделано, чтобы в любой момент выскочить из цикла, например:
do
{
...
if (somethingIsWrong) break;
//more code
...
}
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?
Возможно, это было сделано, чтобы в любой момент выскочить из цикла, например:
do
{
...
if (somethingIsWrong) break;
//more code
...
}
while(false);
Но, как говорили другие, я бы так не сделал.
В 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 фона?
Нет преимуществ. Не делайте этого.
Его можно использовать, чтобы перейти к концу блока, который можно использовать, чтобы избежать вложения вложенных блоков 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);
Это используется в 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)
Это бесполезно, но кодер мог использовать команды множественного разрыва, чтобы выполнить некоторую странную обработку исключений.
do{
if(<something>){...}else{break}
if(<something else>){...}else{break}
...
}while(false)
Предоставлено его глупо, но я нашел что-то вроде старой программы c однажды
Ваша интуиция правильная. Это совершенно бесполезная вещь.
Возможно, что кто-то, кто его закодировал, имел в качестве условия не что иное, как false
, а просто изменил его на false
, а не удалил весь блок, чтобы не потерять эту "историю" кода. Тем не менее, это просто держится за соломинку. Чтобы быть откровенным, это просто простой пример tautology, который не имеет места в коде.
В почти любом другом языке, кроме C/С++, это не дает тактического преимущества.
В C/С++ есть случай с макросами, где do/while (false) облегчает безопасное развертывание макроса во множество операторов. Это выгодно, когда макрос в противном случае выглядит как обычный вызов функции.
Посмотрите на question
ОП спрашивает об этой точной конструкции и объясняет некоторые причины ее использования. Похоже, консенсус заключается в том, что это плохо.
В качестве места для будущего, когда вместо false
ставится другое условие.
Он может использоваться для пропуска выполнения какого-либо кода (например, goto
или что-то еще), но когда я снова смотрю на него, кажется, что существует цикл for
(где операторы if(...) break;
) в do-while
. В противном случае я бы сказал, что это будет Java-версия goto
...
Я использовал это соглашение годами! Это наиболее полезно, когда у вас есть "конвейер" обработки и/или условных проверок. Он просто избегает нескольких уровней вложенных операторов 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.
Я собираюсь догадаться, что автор этого не доверял его коду, поэтому он использовал его пару раз, чтобы проверить, не заставило ли он работать больше, и это археологические остатки этого.
Единственная причина, по которой я могу думать, - создать блок, чтобы сделать переменные, объявленные в {...}
более жесткими, но есть более эффективные способы сделать это (например, создание функций или просто создание блоков - наконечник шляпы Пете Кирхэй).