Правила программирования на С и С++. Главы 1-6 - Функция должна иметь лишь одну точку входа
ОГЛАВЛЕНИЕ
54. Функция должна иметь лишь одну точку входа.
Это правило применимо лишь к программам на С. Вообще, множество переходов goto к одной точке выхода лучше, чем много операторов return. Этим способом вы можете поместить точку прерывания у единственной точки выхода, вместо того чтобы возиться с несколькими прерываниями. Например:
f(){
int возвращаемое_значение = ОШИБКА;
if ( некое_условие )
{
// ...
возвращаемое_значение = НЕЧТО;
goto выход;
}
else
{ // ...
возвращаемое_значение = НЕЧТО_ЕЩЕ;
goto выход;
}
exit:
return возвращаемое_значение;
}
Этот метод не срабатывает в С++, потому что функции конструктора вызываются неявно в качестве части объявления; объявление часто скрывает вызов функции. Если вы пропускаете объявление, то вы пропускаете и вызов конструктора. Например, в следующей программе деструктор для x вызовется, а конструктор нет: foo(){
if ( некое_условие )
goto выход;
некий_класс x; // Конструктор не вызывается. (Оператор goto
// перескакивает через него.)// ...выход:
// Здесь вызывается деструктор для x при выходе x из} // области видимости.Вследствие этой проблемы лучше всего совсем избегать переходов goto в программах на С++.54.1. Всегда предусматривайте возврат значения из блока внешнего уровня.
Иногда, когда подпрограммы короткие, не стоит стараться обеспечить единственную точку выхода. (По моему мнению, правило "избегай запутанности" перекрывает любое другое правило, с которыми оно входит в конфликт). В этой ситуации всегда старайтесь убедиться, что из подпрограммы нет таких путей, которые не проходят через оператор return. Не так:
if ( a ){
// ...
return делай_что_нужно();
}
else
{
// ...
return ОШИБКА;
}
а так: if ( a ){
// ...
return делай_что_нужно();
}
// ...
return ОШИБКА;
В идеале, выход по ошибке организуется из внешнего уровня блока так, чтобы вы правильно обработали неожиданный аварийный выход на внешний уровень.