Я провел некоторое исследование, чтобы выяснить, почему пропущенный возврат не может быть ошибкой, а является неопределенным поведением. Я нашел этот комментарий в отчете об ошибке , который использует следующий пример, чтобы проиллюстрировать, почему не может быть ошибки:
template<typename T>
T maybe_call(std::function<T(void)> f) {
if (f)
return f();
else
abort_program();
// Cannot write a return here, because we have no way to create a value of t
}
Обратите внимание, что этот пример полностью допустим код. Он не имеет возврата во всех филиалах, но все еще нет UB. Это объясняет, почему отсутствие возврата по всем ветвям - это UB, а не ошибка. Пример может быть «исправлен», чтобы объявить abort_program();
как [[noreturn]]
, чтобы сделать его менее встречным аргументом. Я сомневаюсь, что у компиляторов будут проблемы с правильной диагностикой этого примера. Если пропуск возврата приведет к ошибке, правила, возможно, придется немного изменить, потому что только с [[noreturn]]
приведенный выше пример может быть правильно диагностирован.
Однако я ищу другой пример, когда компилятор не может обнаружить пропущенный возврат. В этом комментарии также упоминается, что существуют случаи, которые не могут быть диагностированы компилятором, но я не могу найти такой пример.
Если предупреждение будет надежным (ложные срабатывания, подобные приведенному выше), я могу рассматривать предупреждение как ошибку, чтобы быть на безопасной стороне.
Существуют ли действительно случаи, когда компилятор не может обнаружить пропущенный возврат? Это только в патологическом коде, или это может происходить в повседневном коде тоже? Могу ли я рассчитывать на предупреждение?
Чтобы сделать его ответственным, давайте сосредоточимся на g cc (последняя версия): В каком случае g cc не сможет предупредить о пропущенном возврате?