Todas las otras respuestas defienden la regla 3 de su profesor.
Permítanme decir que estoy de acuerdo con ustedes: la regla es redundante y no lo recomendaría. Es cierto que teóricamente evita errores si siempre agrega llaves. Por otro lado, nunca me he encontrado con este problema en la vida real : al contrario de lo que implican otras respuestas, no me he olvidado de agregar las llaves una vez que se hicieron necesarias. Si usa la sangría adecuada, se vuelve inmediatamente obvio que necesita agregar llaves una vez que se sangra más de una declaración.
La respuesta del "Componente 10" en realidad resalta el único caso concebible en el que esto realmente podría conducir a un error. Pero, por otro lado, reemplazar el código mediante una expresión regular siempre garantiza un cuidado enorme de todos modos.
Ahora echemos un vistazo al otro lado de la medalla: ¿hay alguna desventaja en usar siempre llaves? Las otras respuestas simplemente ignoran este punto. Pero no es una desventaja: se necesita una gran cantidad de espacio vertical de la pantalla, y esto a su vez puede hacer que el código ilegible porque significa que usted tiene que desplazarse más de lo necesario.
Considere una función con muchas cláusulas de protección al principio (y sí, lo siguiente es un código C ++ incorrecto, pero en otros lenguajes esta sería una situación bastante común):
void some_method(obj* a, obj* b)
{
if (a == nullptr)
{
throw null_ptr_error("a");
}
if (b == nullptr)
{
throw null_ptr_error("b");
}
if (a == b)
{
throw logic_error("Cannot do method on identical objects");
}
if (not a->precondition_met())
{
throw logic_error("Precondition for a not met");
}
a->do_something_with(b);
}
Este es un código horrible, y sostengo firmemente que lo siguiente es mucho más legible:
void some_method(obj* a, obj* b)
{
if (a == nullptr)
throw null_ptr_error("a");
if (b == nullptr)
throw null_ptr_error("b");
if (a == b)
throw logic_error("Cannot do method on identical objects");
if (not a->precondition_met())
throw logic_error("Precondition for a not met");
a->do_something_with(b);
}
Del mismo modo, los bucles anidados cortos se benefician al omitir las llaves:
matrix operator +(matrix const& a, matrix const& b) {
matrix c(a.w(), a.h());
for (auto i = 0; i < a.w(); ++i)
for (auto j = 0; j < a.h(); ++j)
c(i, j) = a(i, j) + b(i, j);
return c;
}
Comparar con:
matrix operator +(matrix const& a, matrix const& b) {
matrix c(a.w(), a.h());
for (auto i = 0; i < a.w(); ++i)
{
for (auto j = 0; j < a.h(); ++j)
{
c(i, j) = a(i, j) + b(i, j);
}
}
return c;
}
El primer código es conciso; El segundo código está hinchado.
Y sí, esto puede mitigarse hasta cierto punto poniendo la llave de apertura en la línea anterior. Pero eso aún sería menos legible que el código sin ningún paréntesis.
En resumen: no escriba código innecesario que ocupe espacio en la pantalla.