Страница 61 из 93 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 ОШИБКА; В идеале, выход по ошибке организуется из внешнего уровня блока так, чтобы вы правильно обработали неожиданный аварийный выход на внешний уровень. |