Подтвердить что ты не робот

У этой функции есть явные возвращаемые значения на всех путях управления?

У меня есть функция Heaviside step, ориентированная на единицу для любого типа данных, который я закодировал с помощью:

template <typename T>
int h1(const T& t){
   if (t < 1){
       return 0;
   } else if (t >= 1){
       return 1;
   }
}

В обзоре кода мой обозреватель сказал мне, что на всех путях управления нет явного возврата. И компилятор мне тоже не предупреждает. Но я не согласен; условия являются взаимоисключающими. Как я могу справиться с этим?

4b9b3361

Ответ 1

Это зависит от того, как используется шаблон. Для int вы в порядке.

Но, если t - это тип с плавающей запятой IEEE754 double со значением, установленным на NaN, ни t < 1, ни t >= 1 не являются true и поэтому управление программой достигает конца блока if! Это заставляет функцию возвращаться без явного значения; поведение которого undefined.

(В более общем случае, когда t перегружает операторы < и >= таким образом, чтобы не охватывать все возможности, управление программой достигнет конца блока if без явного return.)

Мораль этой истории здесь заключается в том, чтобы решить, какая ветка должна быть дефолтом, и сделать этот случай else.

Ответ 2

Просто потому, что код правильный, это не значит, что он не может быть лучше. Правильное выполнение является первым шагом в качестве, а не последним.

if (t < 1) {
    return 0;
} else if (t >= 1){
    return 1;
}

Вышеприведенный вариант является "правильным" для любого типа данных t, чем для нормального поведения для < и >=. Но это:

if (t < 1) {
    return 0;
}
return 1;

Легче видеть, проверяя, что каждый случай покрыт, и избегает второго ненужного сравнения вообще (что некоторые компиляторы могут не оптимизироваться). Код не только читается компиляторами, но и людьми, включая вас через 10 лет. Дайте людям перерыв и напишите просто для их понимания.

Ответ 3

Как уже отмечалось, некоторые специальные числа могут быть как <, так и >=, поэтому ваш рецензент просто прав.

Вопрос: что заставило вас хотеть закодировать его таким образом, в первую очередь? Почему вы даже считаете, что жизнь так тяжела для вас самих и для других (людей, которым необходимо поддерживать ваш код)? Просто тот факт, что вы достаточно умны, чтобы вывести, что < и >= должны охватывать все случаи, не означает, что вам нужно сделать код более сложным, чем необходимо. Что касается физики, то и для кода тоже: сделайте все как можно проще, но не проще (я считаю, что Эйнштейн сказал это).

Подумайте об этом. Чего вы пытаетесь достичь? Должно быть что-то вроде этого: "Return 0, если вход меньше 1, в противном случае верните 1". То, что вы сделали, это добавить интеллект, сказав... о, но это означает, что я возвращаю 1, если t больше или равно 1. Этот вид ненужного "x подразумевает y" требует дополнительной мыслительной работы от имени сопровождающего. Если вы считаете, что это хорошо, я бы посоветовал сделать пару лет обслуживания кода самостоятельно.

Если бы это был мой обзор, я бы сделал еще одно замечание. Если вы используете оператор "if", вы можете в основном делать все, что хотите, во всех ветких. Но в этом случае вы ничего не делаете. Все, что вы хотите сделать, это вернуть 0 или 1 в зависимости от того, является ли t < 1 или нет. В таких случаях я думаю, что выражение??: намного лучше и читаемо, чем инструкция if. Таким образом:

return t<1 ? 0 : 1;

Я знаю, что оператор ?: запрещен в некоторых компаниях, и я считаю, что это ужасно. ?: обычно лучше соответствует спецификациям, и он может сделать код намного проще для чтения (если он используется с осторожностью)...