Estoy leyendo algunas notas de mi profesor de C ++ y él escribió lo siguiente:
- Usar sangría // OK
- Nunca confíe en la precedencia del operador: utilice siempre paréntesis // OK
- Utilice siempre un bloque {}, incluso para una sola línea // no está bien , ¿por qué?
- Objeto Const en el lado izquierdo de la comparación // OK
- Use unsigned para variables que son> = 0 // buen truco
- Establezca el puntero en NULL después de la eliminación: doble protección de eliminación // no está mal
La tercera técnica no me resulta clara: ¿qué ganaría al colocar una línea en a { ... }
?
Por ejemplo, tome este código extraño:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
if (i % 2 == 0)
{
j++;
}
}
y reemplazarlo con:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
if (i % 2 == 0)
j++;
¿Cuál es el beneficio de usar la primera versión?
for (unsigned i = 100; i >= 0; --i)
.(i % 2 == 0)
contradice (2). Estás confiando en la precedencia del operador, y el significado es, por supuesto,((i % 2) == 0)
más que(i % (2 == 0))
. Clasificaría la regla 2 como "un sentimiento válido pero 'siempre' está mal".Respuestas:
Intentemos modificar también
i
cuando incrementemosj
:¡Oh no! Viniendo de Python, esto se ve bien, pero de hecho no lo es, ya que es equivalente a:
Por supuesto, este es un error tonto, pero que incluso un programador experimentado podría cometer.
Otra muy buena razón se señala en la respuesta de ta.speot.is .
Un tercero en el que puedo pensar es el anidado
if
:Ahora, suponga que ahora quiere hacerlo
doSomethingElse()
cuandocond1
no se cumple (nueva función). Entonces:lo cual obviamente está mal, ya que se
else
asocia con lo internoif
.Editar: Dado que esto está recibiendo algo de atención, aclararé mi punto de vista. La pregunta que estaba respondiendo es:
Lo que he descrito. Hay algunos beneficios. Pero, en mi opinión, las reglas "siempre" no siempre se aplican. Entonces no apoyo totalmente
No digo que siempre use un
{}
bloque. Si es una condición y comportamiento lo suficientemente simple, no lo haga. Si sospecha que alguien podría venir más tarde y cambiar su código para agregar funcionalidad, hágalo.fuente
i++
antesj++
, ambas variables seguirán estando dentro del alcance cuando se usen.i++;
de una manera que muestre de inmediato que no es parte del bucle. (En el pasado, esto podría haber sido un argumento razonable, y he visto tales problemas. Hace unos 20 años. No desde entonces.)Es muy fácil cambiar accidentalmente el flujo de control con comentarios si no usa
{
y}
. Por ejemplo:Si comenta
do_something_else()
con un comentario de una sola línea, terminará con esto:Se compila, pero
must_always_do_this()
no siempre se llama.Tuvimos este problema en nuestra base de código, donde alguien había entrado para deshabilitar algunas funciones muy rápidamente antes del lanzamiento. Afortunadamente lo atrapamos en la revisión de código.
fuente
must_always_do_this();
se ejecutará si comentas // do_something_else ();if(debug) \n //print(info);
. Básicamente sacó toda una biblioteca.Fortunately we caught it in code review.
¡Ay! Eso suena muy mal.Fortunately we caught it in unit tests.
seria mucho mejor!Tengo mis dudas sobre la competencia del profesor. Considerando sus puntos:
(b*b) - ((4*a)*c)
? Algunas precedentes son obvias (o deberían ser), y los paréntesis adicionales solo aumentan la confusión. (Por otro lado, debe usar los paréntesis en casos menos obvios, incluso si sabe que no son necesarios).{
no es tan visible, por lo que es mejor asumir que siempre está ahí. En el segundo, sin embargo, yo (y la mayoría de las personas con las que he trabajado) no tengo problemas para omitir las llaves para una sola declaración. (Siempre, por supuesto, que la sangría es sistemática y que usa este estilo de manera consistente. (Y muchos programadores muy buenos, que escriben código muy legible, omiten las llaves incluso cuando se formatea de la primera manera).if ( NULL == ptr )
son lo suficientemente feas como para dificultar la legibilidad. Escribe las comparaciones intuitivamente. (Lo que en muchos casos da como resultado la constante a la derecha). Su 4 es un mal consejo; todo lo que hace que el código no sea natural lo hace menos legible.int
está reservada para casos especiales. Para programadores con experiencia en C y C ++, el uso deunsigned
operadores de bits de señales. C ++ no tiene un tipo cardinal real (o cualquier otro tipo de subrango efectivo);unsigned
no funciona para valores numéricos, debido a las reglas de promoción. Presumiblemente, los valores numéricos en los que ninguna operación aritmética tendría sentido, como los números de serie, podrían serlounsigned
. Sin embargo, argumentaría en contra porque envía un mensaje incorrecto: las operaciones bit a bit tampoco tienen sentido. La regla básica es que los tipos integrales sonint
, a menos que exista una razón importante para usar otro tipo.delete this;
es a menudo el caso más frecuente (y no se puede establecerthis
aNULL
), y por otra parte, la mayoríadelete
se encuentran en los destructores, por lo que no puede acceder el puntero más adelante de todos modos. Y configurarloNULL
no hace nada con respecto a ningún otro puntero flotando. Configurar el puntero sistemáticamente paraNULL
dar una falsa sensación de seguridad, y realmente no te compra nada.Mire el código en cualquiera de las referencias típicas. Stroustrup viola todas las reglas que ha dado, excepto la primera, por ejemplo.
Te sugiero que encuentres otro profesor. Alguien que realmente sabe de lo que está hablando.
fuente
delete this
, ¿es más común de lo que he visto? No tiendo a pensar que establecer un puntero en NULL después del uso sea algo tan malo que hacer, pero YMMV. Tal vez soy solo yo, pero la mayoría de sus pautas no parecen tan malas.if (ptr = NULL)
menos que lo escriba comoif ((ptr = NULL))
. Tengo que estar de acuerdo con James Kanze en que la fealdad de tenerNULL
primero lo convierte en un NO definitivo para mí.unsigned
indica una aspiración por parte del programador de que la variable debe representar solo números positivos. La mezcla con números con signo generalmente generará una advertencia del compilador, que probablemente era lo que el profesor tenía la intención.size_t
alguien?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):
Este es un código horrible, y sostengo firmemente que lo siguiente es mucho más legible:
Del mismo modo, los bucles anidados cortos se benefician al omitir las llaves:
Comparar con:
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.
fuente
if (a == nullptr) { throw null_ptr_error("a"); }
como una línea.La base de código en la que estoy trabajando está dispersa con código por personas con aversión patológica a los aparatos ortopédicos, y para las personas que vienen más tarde, realmente puede hacer una diferencia en la mantenibilidad.
El ejemplo problemático más frecuente que he encontrado es este:
Entonces, cuando llego y deseo agregar una declaración de entonces, puedo terminar fácilmente con esto si no tengo cuidado:
Teniendo en cuenta que se tarda ~ 1 segundo para agregar las llaves y se puede ahorrar por lo menos unos minutos confusas depuración, ¿por qué alguna vez no ir con la opción reducido ambigüedad? Me parece una falsa economía.
fuente
if(really long...editor){ do_foo;}
? debido a las dos líneas adicionales en el código.Mi 2c:
Obviamente
No usaría las palabras "nunca y" siempre ", pero en general veo que esta regla es útil. En algunos idiomas (Lisp, Smalltalk) esto no es un problema.
Nunca hago eso y nunca tuve un solo problema, pero puedo ver cómo puede ser bueno para los estudiantes, especialmente. si estudiaron Python antes.
¿Condiciones de Yoda? No por favor. Duele la legibilidad. Simplemente use el nivel de advertencia máximo cuando compile su código.
OKAY. Curiosamente, he oído que Stroustrup no está de acuerdo.
¡Mal consejo! Nunca tenga un puntero que apunte a un objeto eliminado o inexistente.
fuente
unsigned
está roto", uno de los problemas es que cuando C ++ compara tipos con y sin signo de tamaño similar, se convierte en uno sin signo antes de hacer la comparación. Lo que resulta en un cambio de valor. La conversión al firmado no necesariamente sería mucho mejor; la comparación realmente debería tener lugar "como si" ambos valores se convirtieran a un tipo más grande que pudiera representar todos los valores en cualquier tipo.unsigned
. Estoy seguro de que no tiene problemas paraexp(double)
devolver un valor superior aMAX_INT
:-). Pero una vez más, el verdadero problema son las conversiones implícitas.int i = exp( 1e6 );
Es perfectamente válido C ++. Stroustrup en realidad propuso despreciar las conversiones implícitas con pérdidas en un punto, pero el comité no estaba interesado. (Una pregunta interesante: seríaunsigned
->int
se consideraría con pérdida. Consideraría tantounsigned
->int
comoint
->unsigned
con pérdida. Lo que contribuiría en gran medida a hacer queunsigned
OKEs más intuitivo y fácil de entender. Deja en claro la intención.
Y garantiza que el código no se rompa cuando un nuevo usuario podría perderlo sin saberlo
{
, al}
tiempo que agrega una nueva declaración de código.fuente
Makes the intent clear
+1, esta es probablemente la razón más concisa y precisa.Para agregar a las sugerencias muy sensatas anteriores, un ejemplo que encontré al refactorizar algún código de donde esto se vuelve crítico fue el siguiente: estaba alterando una base de código muy grande para cambiar de una API a otra. La primera API recibió una llamada para establecer el Id. De la compañía de la siguiente manera:
mientras que el reemplazo necesitaba dos llamadas:
Me puse a cambiar esto usando expresiones regulares que fue muy exitoso. También pasamos el código a través de un estilo , lo que realmente lo hizo mucho más legible. Luego, a mitad del proceso de revisión, descubrí que en algunas circunstancias condicionales estaba cambiando esto:
A esto:
que claramente no es lo que se requería. Tuve que volver al principio para hacer esto nuevamente tratando el reemplazo como completamente dentro de un bloque y luego alterando manualmente cualquier cosa que terminara pareciendo tonta (al menos no sería incorrecto).
Noto que astyle ahora tiene la opción
--add-brackets
que le permite agregar corchetes donde no los hay y lo recomiendo si alguna vez se encuentra en la misma posición que yo.fuente
#define FOO() func1(); \ func2();
(con un salto de línea después de la barra invertida), lo mismo ocurre con la búsqueda y el reemplazo. Dicho esto, he visto "usar siempre llaves" avanzadas como una regla de estilo precisamente porque le evita envolver todas sus macros de múltiples declaracionesdo .. while(0)
. Pero no estoy de acuerdo.inline
), entonces probablemente debería apuntar a que funcionen de la manera más parecida posible a una función, utilizando eldo { ... } while(0)
truco si es necesario (y muchos paréntesis adicionales. Pero eso todavía no funcionaría) no impida que use llaves en todas partes, si ese es el estilo de la casa. (FWIW: He trabajado en lugares con diferentes estilos de casa, cubriendo todos los estilos discutidos aquí. Nunca he encontrado que ninguno sea un problema serio).Estoy usando en
{}
todas partes, excepto en algunos casos donde es obvio. Una sola línea es uno de los casos:Puede dolerle cuando agrega algún método antes de regresar. La sangría indica que el retorno se está ejecutando cuando se cumple la condición, pero siempre regresará.
Otro ejemplo en C # con el uso de declaración
que es equivalente a
fuente
using
declaración y no tiene que hacerlo :)using
).El ejemplo más pertinente que se me ocurre:
¿Con
if
quéelse
se emparejará? La sangría implica que el externoif
obtiene elelse
, pero en realidad no es así como lo verá el compilador; lo internoif
obtendrá loelse
y lo externoif
no. Tendría que saber eso (o ver que se comporta de esa manera en el modo de depuración) para descubrir por inspección por qué este código puede estar fallando sus expectativas. Se vuelve más confuso si conoce Python; en ese caso, sabe que la sangría define bloques de código, por lo que esperaría que se evalúe de acuerdo con la sangría. C #, sin embargo, no da una vuelta rápida sobre el espacio en blanco.Ahora, dicho esto, no estoy particularmente de acuerdo con esta regla de "siempre usar corchetes" en su cara. Hace que el código sea muy ruidoso verticalmente, lo que reduce la capacidad de leerlo rápidamente. Si la declaración es:
... entonces debería escribirse así. La frase "siempre usar corchetes" suena como "siempre rodear las operaciones matemáticas con paréntesis". Eso convertiría la declaración muy simple
a * b + c / d
en((a * b) + (c / d))
, introduciendo la posibilidad de perderse un paréntesis cercano (la ruina de muchos codificadores), ¿y para qué? El orden de las operaciones es bien conocido y bien aplicado, por lo que los paréntesis son redundantes. Solo usaría paréntesis para imponer un orden de operaciones diferente al que normalmente se aplicaría:a * (b+c) / d
por ejemplo. Las llaves de bloque son similares; utilícelos para definir lo que desea hacer en casos en los que difiere del valor predeterminado y no es "obvio" (subjetivo, pero generalmente de sentido común).fuente
else
el primero con el primero enif
lugar del segundo. Por favor, elimine el voto negativo.Mirando las respuestas, nadie declaró explícitamente el tipo de práctica que uso, contando la historia de su código:
Se convierte en:
Poniendo el
j++
en la misma línea que el if debería indicar a cualquier otra persona, "Solo quiero que este bloque se incrementej
" . Por supuesto, esto solo vale la pena si la línea es lo más simplista posible, porque poner un punto de interrupción aquí, como se dice , no será muy útil.De hecho, acabo de encontrarme con parte de la API de Twitter Storm que tiene este 'tipo' de código en Java, aquí está el fragmento relevante del código de ejecución, en la página 43 de esta presentación de diapositivas :
El bloque de bucle for tiene dos cosas, por lo que no incluiría ese código. Es decir, nunca :
Es horrible y ni siquiera sé si funciona (según lo previsto); no haga esto . Las nuevas líneas y llaves ayudan a distinguir piezas de código separadas pero relacionadas, de la misma manera que una coma o un punto y coma lo hacen en prosa. El bloque anterior es tan malo como una oración muy larga con algunas cláusulas y algunas otras declaraciones que nunca se rompen o se detienen para distinguir partes separadas.
Si realmente quiere telegrafiar a alguien más, es un trabajo de una sola línea, use un operador ternario o un
?:
formulario:Pero esto está al borde del código de golf, y creo que no es una buena práctica (no me queda claro si debo poner el j ++ en un lado del
:
o no). Nota : no he ejecutado un operador ternario en C ++ antes, no sé si esto funciona, pero existe .En breve:
Imagine cómo su lector (es decir, la persona que mantiene el código) interpreta su historia (código). Que sea lo más claro posible para ellos. Si sabe que el codificador / estudiante novato está manteniendo esto, tal vez incluso deje
{}
entrar la mayor cantidad posible, solo para que no se confundan.fuente
for
bucle en una sola línea, ¿por qué no debería funcionar esto? Funciona por la misma razón por la que puede omitir las llaves; la nueva línea simplemente no es significativa en C ++. (3) Su ejemplo de operador condicional, además de ser horrible, no es válido en C ++.Porque cuando tienes dos declaraciones sin
{}
, es fácil pasar por alto un problema. Supongamos que el código se ve así.Se ve bien. El problema con esto es realmente fácil de pasar por alto, especialmente cuando la función que contiene el código es mucho más grande. El problema es que
goto fail
se ejecuta incondicionalmente. Puedes imaginar fácilmente lo frustrante que es esto (haciéndote preguntar por quéhash_update
siempre falla el último , después de todo, todohash_update
funciona bien)Sin embargo, eso no significa que sea para agregar en
{}
todas partes (en mi opinión, ver en{}
todas partes es molesto). Si bien puede causar problemas, nunca lo hizo para mis propios proyectos, ya que mi estilo de codificación personal prohíbe los condicionales sin{}
cuando no están en la misma línea (sí, estoy de acuerdo en que mi estilo de codificación no es convencional, pero me gusta, y yo use el estilo de código del proyecto cuando contribuya a otros proyectos). Esto hace que el siguiente código esté bien.Pero no el siguiente.
fuente
Hace que su código sea más legible al definir claramente el alcance de sus bucles y bloques condicionales. También te salva de errores accidentales.
fuente
wrt 6: es más seguro porque eliminar un puntero nulo es un no-op. Entonces, si accidentalmente pasa por esa ruta dos veces, no causará que la corrupción de la memoria libere memoria que está libre o se ha asignado a otra cosa.
Esto es principalmente un problema con los objetos de ámbito de archivo estático y los singletons que no tienen vidas muy claras y se sabe que se recrearon después de haber sido destruidos.
En la mayoría de los casos, puede evitar la necesidad de esto utilizando auto_ptrs
fuente
NULL
después de eliminarlo. SiNULL
es un valor correcto para el puntero en esas circunstancias; por ejemplo, el puntero apunta a un valor en caché eNULL
indica un caché no válido. Pero cuando ve a alguien configurando un puntero aNULL
como la última línea en un destructor, te preguntas si conoce C ++.)Me gusta la respuesta aceptada de Luchian, de hecho, aprendí por las malas que tiene razón, por lo que siempre uso llaves, incluso para bloques de una sola línea. Sin embargo, personalmente hago una excepción cuando escribo un filtro, como está en su ejemplo. Esta:
me parece abarrotado. Separa el ciclo for y la declaración if en acciones separadas, cuando realmente su intención es una sola acción: contar todos los enteros divisibles por 2. En un lenguaje más expresivo, esto podría escribirse algo así como:
En los idiomas que carecen de cierres, el filtro no se puede expresar en una sola declaración, sino que debe ser un ciclo for seguido de una declaración if. Sin embargo, todavía es una acción en la mente del programador, y creo que debería reflejarse en el código, así:
fuente
for (int i = 0; i < 100; i += 2);
, en aras de continuar la discusión sobre la sangría ;-) Probablemente haya una pelea de combates completamente diferente que podamos tener, cómo "mejor" expresar la lógica "para cada unoi
en un cierto rango con una determinada propiedad". en C ++ sin bucle, utilizando una combinación de pesadilla de algoritmos estándar,filter_iterator
y / ocounting_iterator
.i
en un determinado rango con una determinada propiedad". Es solo que generalmente en SO, las personas son muy rápidas para ignorar la pregunta real a favor de un enfoque completamente diferente al ejemplo dado. Pero la sangría es importante , por lo que no lo hacemos ;-)Una opción para ayudar a prevenir los errores que se han descrito anteriormente es alinear lo que desea que suceda cuando no usa llaves. Hace que sea mucho más difícil no notar los errores cuando intentas modificar el código.
fuente
else
que no está asociado con unif
.Si eres un compilador, no hace ninguna diferencia. Los dos son iguales.
Pero para los programadores, el primero es más claro, fácil de leer y menos propenso a errores.
fuente
{
en su propia línea, de todos modos.Otro ejemplo de agregar llaves. Una vez que estaba buscando un error y encontré dicho código:
Si lee el método línea por línea, notará que hay una condición en el método que se devuelve si no es cierto. Pero en realidad se parece a otros 100 controladores de eventos simples que establecen algunas variables en función de algunas condiciones. Y un día aparece el Codificador rápido y agrega una declaración de configuración de variables adicional al final del método:
Como resultado, SetAnotherVariableUnconditionnaly se ejecuta cuando SomeConditionIsMet (), pero el tipo rápido no lo notó porque todas las líneas tienen un tamaño casi similar e incluso cuando la condición de retorno está indentada verticalmente no es tan notable.
Si el retorno condicional se formatea así:
es muy notable y Fast Coder lo encontrará de un vistazo.
fuente
return
declaración resaltada de sintaxis dentro del cuerpo de una función antes de agregarle algo, no debe permitir que el codificador rápido se acerque a su código. No evitarás que un tipo así mire tu código al incluir llaves.Considero que el primero es claro y luego el segundo. Da la sensación de cerrar las instrucciones, con poco código está bien cuando el código se vuelve complejo
{...}
ayuda mucho incluso si esendif
obegin...end
fuente
Es mejor establecer el puntero en NULL cuando haya terminado con él.
Aquí hay un ejemplo de por qué:
La clase A hace lo siguiente:
La clase B hace lo siguiente
En este punto, tanto la Clase A como la Clase B tienen punteros que apuntan al mismo bloque de memoria, en lo que respecta a la Clase A, este bloque de memoria no existe porque ha terminado con él.
Considere el siguiente problema:
¿Qué sucede si hubo un error lógico en la Clase A que resultó en la escritura en la memoria que ahora pertenece a la Clase B?
En este caso particular, no obtendrá un error de excepción de acceso incorrecto porque la dirección de memoria es legal, mientras que la clase A ahora está corrompiendo efectivamente los datos de clase B.
La clase B puede bloquearse eventualmente si encuentra valores inesperados y, cuando se bloquea, lo más probable es que pases bastante tiempo buscando este error en la clase B cuando el problema está en la clase A.
Si hubiera establecido el puntero de memoria eliminado en NULL, habría recibido un error de excepción tan pronto como cualquier error lógico en la Clase A intentara escribir en el puntero NULL.
Si le preocupa el error lógico con doble eliminación cuando los punteros son NULL por segunda vez, agregue aserción para esto.
Además: si va a rechazar el voto, explique.
fuente
Siempre tener llaves es una regla muy simple y robusta. Sin embargo, el código puede parecer poco elegante cuando hay muchas llaves. Si las reglas permiten omitir llaves, entonces debería haber reglas de estilo más detalladas y herramientas más sofisticadas. De lo contrario, puede resultar fácilmente con un código caótico y confuso (no elegante). Por lo tanto, buscar una regla de estilo individual separada del resto de guías de estilo y herramientas utilizadas es probablemente infructuoso. Solo traeré algunos detalles importantes sobre esa regla # 3 que ni siquiera se han mencionado en otras respuestas.
El primer detalle interesante es que la mayoría de los defensores de esa regla acuerdan violarla en caso de
else
. En otras palabras, no exigen en revisión dicho código:En cambio, si lo ven, incluso pueden sugerir que lo escriban así:
Eso es técnicamente una violación de esa regla ya que no hay llaves entre
else
yif
. Tal dualidad de la regla aparece cuando se intenta aplicarla a la base de código automáticamente con una herramienta sin sentido. De hecho, por qué discutir, simplemente deje que una herramienta aplique el estilo automáticamente.El segundo detalle (que a menudo también olvidan los defensores de esa regla) es que los errores que pueden ocurrir nunca se deben solo a violaciones de esa regla # 3. En realidad, casi siempre implican violaciones de la regla n. ° 1 (con las que nadie discute). Nuevamente, desde el punto de vista de las herramientas automáticas, no es difícil hacer una herramienta que se queje inmediatamente cuando se infringe la regla n. ° 1, por lo que la mayoría de los errores pueden detectarse a tiempo.
El tercer detalle (que a menudo los opositores olvidan de esa regla) es la naturaleza confusa de la declaración vacía que está representada por un punto y coma. La mayoría de los desarrolladores con algo de experiencia se confundieron tarde o temprano por un punto y coma fuera de lugar o por una declaración vacía que se escribe con un punto y coma. Dos llaves en lugar de un punto y coma son visualmente más fáciles de detectar.
fuente
Tengo que admitir que no siempre se usa
{}
para una sola línea, pero es una buena práctica.Digamos que escribe un código sin paréntesis que se ve así:
para (int i = 0; i <100; ++ i) para (int j = 0; j <100; ++ j) DoSingleStuff ();
Y después de un tiempo, desea agregar en
j
bucle algunas otras cosas y simplemente lo hace alineando y olvidando agregar corchetes.La desasignación de memoria es más rápida. Digamos que tiene un gran alcance y crea grandes matrices en el interior (sin
new
que estén en la pila). Esos arreglos se eliminan de la memoria justo después de que deja el alcance. Pero es posible que use esa matriz en un lugar y estará en la pila por un tiempo y será una especie de basura. Como una pila tiene un tamaño limitado y bastante pequeño, es posible superar el tamaño de la pila. Entonces, en algunos casos, es mejor escribir{}
para evitar eso. NOTA: esto no es para una sola línea, sino para tales situaciones:if (...) {// SomeStuff ... {// no tenemos if, while, etc. // SomeOtherStuff} // SomeMoreStuff}
La tercera forma de usarlo es similar a la segunda. Simplemente no es para hacer una pila más limpia sino para abrir algunas funciones. Si usa
mutex
funciones largas, generalmente es mejor bloquear y desbloquear justo antes de acceder a los datos y justo después de terminar de leer / escribir eso. NOTA de esta manera se usa si tiene alguna propiaclass
ostruct
conconstructor
ydestructor
para bloquear la memoria.Qué es más:
if (...) if (...) SomeStuff (); else SomeOtherStuff (); // va al segundo si, pero la alineación muestra que está encendido primero ...
En general, no puedo decir, cuál es la mejor manera de usar siempre
{}
para una sola línea, pero no es nada malo hacer eso.EDICIÓN IMPORTANTE Si escribe corchetes de compilación de código para una sola línea no hace nada, pero si su código será interpretado, ralentiza el código muy ligeramente. Muy ligeramente.
fuente
Hay varias formas posibles de escribir declaraciones de control; ciertas combinaciones de ellas pueden coexistir sin afectar la legibilidad, pero otras combinaciones causarán problemas. El estilo
coexistirá cómodamente con algunas de las otras formas de escribir declaraciones de control, pero no tan bien con otras. Si las declaraciones controladas de varias líneas se escriben como:
entonces será visualmente obvio qué
if
afirmaciones controlan una sola línea y cuáles controlan varias líneas. Sin embargo, si lasif
declaraciones de varias líneas se escriben como:entonces la probabilidad de que alguien intente extender una
if
construcción de una sola declaración sin agregar las llaves necesarias puede ser mucho mayor.La declaración de una sola declaración en la línea siguiente
if
también puede ser problemática si la base de código hace un uso significativo del formularioMi preferencia es que tener la declaración en su propia línea generalmente mejora la legibilidad, excepto en los casos en que hay muchas
if
declaraciones con bloques de control similares, por ejemploen cuyo caso generalmente precederé y seguiré dichos grupos de
if
declaraciones con una línea en blanco para separarlas visualmente de otro código. Tener una gama de declaraciones que comiencen conif
la misma sangría proporcionará una indicación visual clara de que hay algo inusual.fuente