c++ - retornar - ¿Esta función tiene valores de retorno explícitos en todas las rutas de control?
funciones que retornan valores en c++ (3)
Tengo una función de paso Heaviside centrada en la unidad para cualquier tipo de datos, que he codificado usando:
template <typename T>
int h1(const T& t){
if (t < 1){
return 0;
} else if (t >= 1){
return 1;
}
}
En la revisión de código, mi revisor me dijo que no hay un retorno explícito en todas las rutas de control. Y el compilador tampoco me avisa. Pero no estoy de acuerdo; Las condiciones son mutuamente excluyentes. ¿Cómo trato con esto?
Como se señaló, algunos números especiales pueden ser
<
y
>=
, por lo que su revisor simplemente tiene razón.
La pregunta es: ¿qué te hizo querer codificarlo así en primer lugar?
¿Por qué considera hacer la vida tan difícil para usted y para los demás (las personas que necesitan mantener su código)?
El hecho de que sea lo suficientemente inteligente como para deducir que
<
y
>=
debe cubrir todos los casos no significa que deba hacer que el código sea más complejo de lo necesario.
Lo que vale para la física también vale para el código: hacer las cosas lo más simple posible, pero no más simple (creo que Einstein dijo esto).
Piénsalo. ¿Qué estás intentando lograr? Debe ser algo como esto: ''Devuelve 0 si la entrada es menor que 1, devuelve 1 de lo contrario''. Lo que has hecho es agregar inteligencia al decir ... oh, pero eso significa que devuelvo 1 si t es mayor o igual a 1. Este tipo de ''x implica y'' innecesario requiere un trabajo de reflexión adicional en nombre del responsable. Si cree que es algo bueno, le aconsejaría que haga un par de años de mantenimiento del código usted mismo.
Si fuera mi crítica, haría otra observación.
Si usa una declaración ''if'', básicamente puede hacer lo que quiera en todas las ramas.
Pero en este caso, no haces ''nada''.
Todo lo que quiere hacer es devolver 0 o 1 dependiendo de si t <1 o no.
En esos casos, creo que la declaración ''?:'' Es
mucho
mejor y más legible que la declaración
if
.
Así:
return t<1 ? 0 : 1;
Sé que el operador
?:
Está prohibido en algunas empresas, y creo que es algo horrible.
?:
generalmente coincide mucho mejor con las especificaciones, y puede hacer que el código sea mucho más fácil de leer (si se usa con cuidado) ...
Depende de cómo se use la plantilla.
Para un
int
, estás bien.
Pero
, si
t
es un tipo
double
coma flotante IEEE754 con un valor establecido en
NaN
, ni
t < 1
ni
t >= 1
son
true
por lo que el control del programa llega al final del bloque
if
.
Esto hace que la función regrese sin un valor explícito;
cuyo comportamiento es indefinido.
(En un caso más general, donde
T
sobrecarga los operadores
<
y
>=
de tal manera que no cubra todas las posibilidades, el control del programa llegará al final del bloque
if
sin
return
explícito).
La moraleja de la historia aquí es decidir qué rama debería ser la predeterminada y hacer que esa sea la
else
.
El hecho de que el código sea correcto no significa que no pueda ser mejor. La ejecución correcta es el primer paso en calidad, no el último.
if (t < 1) {
return 0;
} else if (t >= 1){
return 1;
}
Lo anterior es "correcto" para cualquier tipo de datos de
t
que tenga un comportamiento sensato para
<
y
>=
.
Pero esto:
if (t < 1) {
return 0;
}
return 1;
Es más fácil ver mediante la inspección que todos los casos están cubiertos y evita la segunda comparación innecesaria por completo (que algunos compiladores podrían no haberse optimizado). El código no solo lo leen los compiladores, sino también los humanos, incluido usted dentro de 10 años. Dé un descanso a los humanos y escriba más simplemente para su comprensión también.