Конструкция делает .. в то время как (ложь) способствует лучшему потоку управления? - PullRequest
3 голосов
/ 06 декабря 2010

Я недавно сталкивался с этим кодом:

do {
    if ( ! checkSomething() )
        break;

    // some code

    if ( ! checkSomeOtherThing() )
        break;

    // some other code
} while(false);

// some final code

Программист, написавший его, написал комментарий в духе "cleaner control flow".

На мой взгляд, оригиналкод мог бы выглядеть лучше, если бы он был преобразован во что-то другое.Но есть ли правда в этом утверждении?Эта конструкция хороша?

Ответы [ 4 ]

6 голосов
/ 06 декабря 2010

Я считаю, что это намного легче читать, и он дает идентичный результат:

if ( checkSomething() )
{
    // some code
    if ( checkSomeOtherThing() )
    {
        // some other code
    }
}
// some final code

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

3 голосов
/ 06 декабря 2010

Это эквивалентно goto.

. В таких ситуациях лучше использовать goto, чем использовать некрасивый хак.

Изменение его на использование goto делает его намного более читабельным:

if (!checkSomething())
    goto Done;

// some code

if (!checkSomeOtherThing())
    goto Done;

// some other code
Done: //some final code
2 голосов
/ 06 декабря 2010

Если вы не возражаете против циклов, содержащих несколько операторов break, то единственная проблема здесь заключается в том, что C (по понятным причинам) не позволяет вырваться из пустого блока, следовательно, «не цикл», который какой-то ничего не подозревающий будущий сопровождающий может принять за реальный цикл.

Я думаю, следующие соображения:

  • если есть только два break пункта, что плохого в двух if утверждениях?
  • если имеется более двух точек останова, отступ с операторами if может стать неприятным, и это спасает это, но опять же, функция выполняет слишком много? И даже если нет, было бы лучше просто использовать goto и избежать странностей цикла, который не зацикливается?

Поскольку вы помечали этот язык, не зависящий от языка, я использовал макроизированный язык ассемблера с block ... endblock, из которого вы могли выйти. Это приводит к достаточно хорошему коду для проверки необходимых условий, таких как:

block
    breakif str1 == null
    breakif str2 == null
    get some combined property of str1 and str2
    breakif some other condition that stops us getting on with it
    get on with it
endblock

На самом деле, это не было breakif str1 == null, это было breakifeq.p str1, null, или что-то в этом роде, но я точно забыл, что.

0 голосов
/ 06 декабря 2010

Я видел форму do-while, принятую в качестве стандарта, которому соответствовали кодеры. Преимущество состоит в том, что он сообщает и реализует, что цикл всегда будет выполняться по крайней мере один раз. Это помогает согласованно изолировать ситуации, когда происходит что-то иное, то есть когда код в цикле не выполняется.

Этот стандарт был принят, потому что применялась методика Варнье-Орра.

...