Я использую do { } while (false);
время от времени, когда это кажется подходящим. Я вижу, что это что-то вроде блока try / catch, в котором у меня есть код, который настроен как блок с серией решений с возможными исключениями, и мне нужно, чтобы в конце были различные пути через правила и логику для объединения блока.
Я почти уверен, что использую эту конструкцию только для программирования на С, и это не очень часто.
В приведенном вами конкретном примере из серии вызовов функций, которые будут выполняться один за другим с выполнением полной серии или серией остановленной в случае обнаружения ошибки, я, вероятно, просто использовал бы операторы, проверяющие переменную ошибки .
{
int iCallStatus = 0;
iCallStatus = doFunc1();
if (iCallStatus == 0) iCallStatus = doFunc2();
if (iCallStatus == 0) icallStatus = doFunc3();
}
Это коротко, и смысл понятен и понятен даже без комментариев.
Время от времени я сталкиваюсь с тем, что этот довольно простой последовательный поток процедурных шагов не применим к конкретному требованию. Что мне нужно, так это создать блок кода с различными решениями, обычно включающими циклы или итерации по некоторым сериям объектов данных, и я хочу рассматривать эту серию как разновидность транзакции, в которой транзакция будет зафиксирована, если не будет ошибки или отменена если при обработке транзакции обнаруживается какая-либо ошибка. Как часть этого блока данных, я могу создать набор временных переменных для области действия do { } while (false);
. Когда я использую это, я всегда добавляю комментарий, указывающий, что это одна итерация, выполняемая в то время, что-то вроде:
do { // single loop code block begins
// block of statements for business logic with single ending point
} while (false); // single loop code block ends
Когда я думаю, что эта конструкция необходима, я смотрю, нужно ли выполнить рефакторинг кода или более подходящей является функция или набор функций.
Причина, по которой я предпочитаю эту конструкцию вместо использования оператора goto
, заключается в том, что использование скобок и отступов облегчает чтение исходного кода. С помощью моего редактора я легко могу найти верх и низ блока, а отступ позволяет визуализировать код как блок с единственной точкой входа и известной конечной точкой. В блоке может быть несколько точек выхода, но я знаю, где они все окажутся. Использование этого означает, что я могу создавать локализованные переменные, которые выйдут из области видимости, хотя использование скобок без do { } while (false);
также делает это. Однако я использую do while, потому что мне нужен перерыв; способность также.
Я бы рассмотрел использование этого стиля в некоторых из следующих условий. Если реализуемая бизнес-логика требует набора переменных, которые совместно используются и на которые ссылаются различные возможные пути выполнения, которые воссоединяются. Если бизнес-логика сложна с несколькими состояниями и проверяет несколько уровней операторов if и если во время обработки обнаружена ошибка, устанавливается индикация ошибки и обработка прерывается.
Единственное, о чем я могу подумать, когда я использовал это, было с чем-то немного грубым, и это помогло уточнить и упростить прерывание обработки. Так что в основном я использовал это похоже на создание исключения с помощью try / catch.