Есть ли принципиальная разница: ставить или не ставить else, если в if-блоке есть return или throw?

Допустим, есть следующий код:

if (condition)
    return 0;
else
    DoSomething();

Его можно переписать как:

if (condition)
    return 0;
DoSomething();

В обоих случаях при условии, что condition == true, будет выполнен возврат из функции, а в противном случае будет вызвана функция DoSomething(). Аналогичный пример можно привести с оператором throw вместо return. То есть логически в этих двух случаях (с else и без) разницы не будет абсолютно никакой.

Вопрос: есть ли какие-либо веские причины обязательно ставить или обязательно не ставить else в подобных ситуациях? Возможно, есть какие-то, хотя бы незначительные, различия в производительности между приведёнными двумя примерами (с else и без)?


Ответы (2 шт):

Автор решения: Kromster

Основная разница должна быть в семантике и том, что должен понять тот, кто будет читать этот код в будущем. Все зависит от окружающего кода и вкладываемого смысла.

Если этот код записан в функции из 3 строчек и больше внутри ничего нет, то никакой особой разницы нет. Если же это функция из 5+ строк, то семантика уже проявляется (и зависит от вложенности и расположения фрагмента). Ниже речь об этом:


if A then return 0 else B;

Так скорее выглядит код внутри цикла, когда (не)найдено некоторое искомое значение и этого достаточно для определения результата функции. Или какой-то вызов метода создания/инициализации чего-либо.


if A then return 0;

Так обычно выглядят guard-statements / early-exit statements - условия проверяемые в самом начале функции, когда заранее можно определить конечный результат не выполняя основное тело функции.


Касательно Return или это Throw - не принципиально. В случае Return мы определяем "хороший" выход, а в случае Throw - "плохой".

→ Ссылка
Автор решения: AR Hovsepyan

Если в теле else выполняются действия, которые не являются валидными (например: "если речь идет только о жидких и твердых объектах и это не жидкость, то бросим в корзину для мусора"), если не выполняется условие condition (допустим оно проверяет является ли объект жидким?). Не выполнив в теле else эти действия, вы по любому выполняете их, но бросить жидкий объект в корзину нельзя, и это приводит к нарушению правил (в частности крушение программы, генерация исключения и т.д.). Написав то же самое в теле else, действия вы выполняете при условии, если condition не выполняется (не жидкий объект), и нет проблем...

Примером может являться ответ, следующего

вопроса:

template<typename ...T>
bool implic(T... args) {
    if  (!(std::is_integral_v<decltype(args)> && ...))
        return false; 
    else    return(args | ...);          
}

Если передать в функцию не интегральный тип, то вернет ложь, а если убрать else , то специализация не компилируется, если с объектом типа невозможно выполнить битовую операцию. Так что тут else убрать нельзя.

→ Ссылка