Иногда ваш компилятор не может сделать вывод, что ваша функция на самом деле имеет нет пропущенного возврата. В таких случаях существует несколько решений:
Пусть
if (foo == 0) {
return bar;
} else {
return frob;
}
Перестрой свой код
if (foo == 0) {
return bar;
}
return frob;
Это хорошо работает, если вы можете интерпретировать оператор if как своего рода брандмауэр или предварительное условие.
преждевременное прекращение ()
(см. Комментарий Дэвида Родригеса.)
if (foo == 0) {
return bar;
} else {
return frob;
}
abort(); return -1; // unreachable
Верните что-нибудь еще соответственно. Комментарий говорит вам и другим программистам, почему это так.
бросок
#include <stdexcept>
if (foo == 0) {
return bar;
} else {
return frob;
}
throw std::runtime_error ("impossible");
Не контрмер: Точка выхода из одной функции
Не используйте один возврат-на-функцию a.k.a. одиночная точка-выход-точка в качестве обходного пути. Это устарело в C ++, потому что вы почти никогда не знаете, куда выйдет функция:
void foo(int&);
int bar () {
int ret = -1;
foo (ret);
return ret;
}
Выглядит красиво и похоже на SFEP, но обратное проектирование сторонней проприетарной libfoo
показывает:
void foo (int &) {
if (rand()%2) throw ":P";
}
Кроме того, это может привести к ненужной потере производительности:
Frob bar ()
{
Frob ret;
if (...) ret = ...;
...
if (...) ret = ...;
else if (...) ret = ...;
return ret;
}
потому что:
class Frob { char c[1024]; }; // copy lots of data upon copy
И каждая изменяемая переменная увеличивает цикломатическую сложность вашего кода. Это означает, что больше кода и больше состояния для тестирования и проверки, в свою очередь, означает, что вы высасываете больше состояния из мозга сопровождающих, в свою очередь, означает меньшее качество мозга сопровождающего.
Последнее, что не менее важно: некоторые классы не имеют конструкции по умолчанию, и вам, возможно, придется написать действительно поддельный код, если это вообще возможно:
File mogrify() {
File f ("/dev/random"); // need bogus init
...
}
Не делай этого.