Pregunta

Como parte de un documento de estándares de código que escribí hace un tiempo atrás, hago cumplir "siempre hay que utilizar llaves para bucles y / o bloques de código condicional, incluso (especialmente) si son sólo una línea."

Ejemplo:

// this is wrong
if (foo) 
    //bar
else 
    //baz
while (stuff)
    //things

// This is right.
if (foo) {
    // bar
} else {
    // baz
}
while (things) {
    // stuff
}

Cuando no preparas una sola línea, y luego alguien hace un comentario a cabo, estás en problemas. Si no preparas una sola línea, y la sangría no muestra la misma en la máquina de otra persona ... que estás en problemas.

Por lo tanto, la pregunta: ¿hay buenas razones por las que esto sería una norma errónea o de otra manera no razonable? Ha habido cierto debate sobre ello, pero nadie me puede ofrecer un mejor argumento en contra que "se siente fea".

¿Fue útil?

Solución

hago cumplir esto a un punto, con excepciones menores de si las declaraciones que evalúan a cualquiera de retorno o para continuar un bucle.

Por lo tanto, esto es correcto por mi estándar:

if(true) continue;

Como es esto

if(true) return;

Sin embargo, la regla es que es o bien un retorno o continuar, y es todo en la misma línea. De lo contrario, se prepara para todo.

El razonamiento es tanto por el bien de tener una forma estándar de hacerlo, y para evitar el problema comentando que usted ha mencionado.

Otros consejos

El mejor argumento en contra que puedo ofrecer es que la línea (s) adicional tomado por el espacio a reducir la cantidad de código se puede ver a la vez, y la cantidad de código se puede ver al mismo tiempo es un factor importante en lo fácil que es para detectar errores. Estoy de acuerdo con las razones por las que has dado para la inclusión de los apoyos, pero en muchos años de C ++ sólo puedo pensar en una ocasión en que he cometido un error como resultado y estaba en un lugar donde no tenía ninguna buena razón para saltarse las llaves de todas formas. Por desgracia, no se sabía si ver esas líneas adicionales de código cada vez ayudado en la práctica o no.

Estoy tal vez más sesgada porque me gusta la simetría de hacer coincidir los apoyos al mismo nivel de sangría (y la agrupación implícita de las declaraciones que aparecen como un bloque de ejecución) - lo que significa que los frenos añadiendo todos el tiempo agrega una gran cantidad de líneas para el proyecto.

Veo esta regla como un exceso. normas draconianas no son buenos programadores, que sólo disminuyen las probabilidades de que un vago va a hacer un lío.

Los ejemplos se dan son válidos, pero tienen mejores soluciones que forzar los apoyos:

  

Cuando no preparas una sola línea, y luego alguien hace un comentario a cabo, estás en problemas.

Dos prácticas resolver esto mejor, elegir uno:

1) Comentario la if, while, etc. antes de la de una sola línea con el de una sola línea. Es decir. tratar

if(foo)
    bar();

como cualquier otra declaración de líneas múltiples (por ejemplo, una asignación con múltiples líneas, o una llamada de función de varias líneas):

//if(foo)
//    bar();

2) Prefijo la // con un ;:

if(foo)
;//    bar();
  

Si no preparas una sola línea, y la sangría no muestra la misma en la máquina de otra persona ... que estás en problemas.

No, no estás; el código funciona de la misma, pero es más difícil de leer. Arreglar su sangría. Recoger las fichas o espacios y seguir con ellos. No mezclar las fichas y espacios para el sangrado. Muchos editores de texto fijará automáticamente por usted.

escribir código Python. Que va a arreglar por lo menos algunos hábitos malos de sangría.

Además, las estructuras como } else { ven como una versión nethack de un caza TIE a mí.

  

¿Hay buenas razones por las que esto sería una norma errónea o de otra manera no razonable? Ha habido cierto debate sobre ello, pero nadie me puede ofrecer un mejor argumento en contra que "se siente fea".

Los apoyos redundantes (y entre paréntesis) son el desorden visual. Visual desorden hace que el código más difícil de leer. El código más difícil es leer, más fácil es para ocultar errores.

int x = 0;
while(x < 10);
{
    printf("Count: %d\n", ++x);
}

Forzar a los apoyos no ayuda a encontrar el error en el código de seguridad.

P.S. Soy un abonado a la "cada regla debe decir por qué" de la escuela, o como el Dalai Lama dijo, "conocer las reglas para que puedan romper adecuadamente."

Yo todavía no tienen a nadie llegar a una buena razón para no utilizar siempre llaves.

Los beneficios superan con creces cualquier "Se siente feo" razón por la que he oído.

Codificación estándar existen para hacer el código más fácil de leer y reducir errores.

Esta es una norma que realmente vale la pena.

Me resulta difícil discutir con los estándares que reducen los errores y hacer que el código sea más legible codificación. Se puede sentir feo para algunas personas en un primer momento, pero creo que es una regla perfectamente válido para poner en práctica.

Me paro en la base de que los apoyos deben coincidir según la sangría.

// This is right.
if (foo) 
{
    // bar
}
else 
{
    // baz
}

while (things) 
{
    // stuff
}

En cuanto a los dos ejemplos, que consideraría la suya ligeramente menos legible ya que encontrar la coincidencia de cierre de paréntesis, puede ser difícil, pero más fácil de leer en los casos en que la sangría no es correcta, al tiempo que permite la lógica para insertarse más fácil. No es una gran diferencia.

Incluso si la sangría es incorrecta, la sentencia if se ejecutará el siguiente comando, independientemente de si es en la siguiente línea o no. La única razón para no poner los dos comandos en la misma línea es para el apoyo depurador.

La única gran ventaja que veo es que es más fácil añadir más declaraciones a los condicionales y bucles que se apoyan, y que no tiene muchas pulsaciones de teclas adicionales para crear las llaves en la salida.

Mi regla personal es si se trata de un tiempo muy corto 'si', a continuación, poner todo en una línea:

if(!something) doSomethingElse();

En general yo uso esto sólo cuando hay un montón de IFS como esta en la serie.

if(something == a) doSomething(a);
if(something == b) doSomething(b);
if(something == b) doSomething(c);

Esa situación no se presenta muy a menudo aunque, por lo contrario, siempre uso los frenos.

En la actualidad, trabajo con un equipo que vive por esta norma, y, mientras estoy resistentes a ella, cumplo por el bien de la uniformidad.

Me opongo por la misma razón me opongo a los equipos que prohíben el uso de excepciones o plantillas o macros:. Si usted elige utilizar un lenguaje, el uso conjunto de la lengua Si las llaves son opcionales en C y C ++ y Java, la obligatoriedad de que, por convención, muestra algo de miedo de la propia lengua.

Yo entiendo los riesgos descritos en otras respuestas aquí, y entiendo el ansia de uniformidad, pero no soy simpático a subconjuntos de idioma Salvo alguna estricta razón técnica , tales como el único compilador para algunos medio ambiente no acomodar plantillas, o interacción con código C opone amplio uso de excepciones.

La mayor parte de mi día consiste en la revisión de los cambios presentados por los programadores junior, y los problemas comunes que surgen tienen nada que ver con la colocación del aparato ortopédico o declaraciones de liquidación en el lugar equivocado. El peligro es exagerado. Prefiero pasar mi tiempo a centrarse en más problemas materiales de buscar violaciónes de lo que el compilador aceptará sin problemas.

La única forma de normas de codificación se puede seguir así por un grupo de programadores es mantener el número de reglas a un mínimo.

Equilibrar el beneficio contra el costo (cada regla adicional confunde y confunde a los programadores, y después de un cierto umbral, en realidad reduce la posibilidad de que los programadores seguir cualquiera de las reglas)

Por lo tanto, para hacer un estándar de codificación:

  • Asegúrese de que puede justificar toda regla con una clara evidencia de que es mejor que las alternativas.

  • buscar alternativas a la regla - ¿es realmente necesario? Si todos los programadores utilizar espacios en blanco (líneas en blanco y la sangría), así, una sentencia if es muy fácil de leer, y no hay manera de que incluso un programador novato puede confundir una sentencia dentro de un "si" de una declaración que es independiente. Si usted está recibiendo un montón de errores relacionados con si-determinación del alcance, la causa es, probablemente, que tiene un estilo pobre whitepsace / muesca que hace que el código sea innecesariamente difícil de leer.

  • Dar prioridad a sus reglas por su efecto mensurable sobre la calidad del código. Cuántos errores se puede evitar mediante la aplicación de una regla (por ejemplo, "siempre comprobar la nula", "siempre validar los parámetros con una aserción", "siempre escribir una prueba de unidad" frente a "siempre añadir algunos apoyos, incluso si no son necesarios") . Las reglas anteriores le ahorrará miles de insectos de un año. La regla corsé que podría salvar a uno. Tal vez.

  • Mantener las normas más eficaces, y desechar la paja. Tamo es, como mínimo, una regla que le costará más de implementar que cualquier error que pueda ocurrir al ignorar la regla. Pero, probablemente, si usted tiene más de alrededor de 30 normas clave, sus programadores no harán caso de muchos de ellos, y sus buenas intenciones serán como el polvo.

  • Fuego cualquier programador que comenta a cabo bits aleatorios de código sin leerlo: -)

P.S. Mi postura sobre el aparato ortopédico: Si el "if" o los contenidos de la misma son a la vez una sola línea, entonces es posible omitir las llaves. Eso significa que si usted tiene un caso que contiene un comentario de una sola línea y una sola línea de código, los contenidos tomar dos líneas, y por lo tanto se requiere que los apoyos. Si la condición if abarca dos líneas (incluso si los contenidos son una sola línea), entonces usted necesita aparatos de ortodoncia. Esto significa que sólo omite los apoyos en los casos triviales, simples, leer fácilmente que los errores no se hacen en la práctica. (Cuando una instrucción está vacía, no uso los frenos, pero siempre pongo un comentario que indica claramente que está vacía, y intencionalmente pero eso es limítrofe en un tema diferente:. Ser explícito en el código de modo que los lectores saben que significaba un ámbito que sea vacío en lugar de sonar el teléfono y se olvidó de terminar el código)

Muchas languanges tienen una sintaxis para trazadores de líneas uno como este (estoy pensando en Perl en particular) para hacer frente a tales "fealdad". Así que algo como:

if (foo)     
//bar
else     
//baz

puede ser escrito como un ternaria usando el operador ternario:

foo ? bar : baz

y

while (something is true)
{
blah 
}

puede escribirse como:

blah while(something is true)

Sin embargo, en los idiomas que no tienen este "azúcar" Sin duda alguna lo incluirá los aparatos de ortodoncia. Como dijiste que evita errores innecesarios del arrastramiento y hace que la intención del programador más clara.

No estoy diciendo que no es razonable, pero en más de 15 años de codificación con lenguajes como C, no he tenido un solo problema con la omisión de los aparatos de ortodoncia. Al comentar a cabo una rama suena como un problema real en teoría -. Yo he visto nunca que esto ocurra en la práctica

Otra de las ventajas de utilizar siempre los apoyos es que hace que la búsqueda y reemplazo y las operaciones automatizadas similares más fácil.

Por ejemplo: Supongamos que noto que functionB generalmente se llama inmediatamente después functionA, con un patrón similar de argumentos, y por lo que quiero refactor que duplica código en un nuevo combined_function. Una expresión regular fácilmente podría manejar esta refactorización si usted no tiene una poderosa herramienta lo suficientemente refactorización (^\s+functionA.*?;\n\s+functionB.*?;) pero, sin aparatos, un enfoque de expresiones regulares simple podría fallar:

if (x)
  functionA(x);
else
  functionA(y);
functionB();

se convertiría

if (x)
  functionA(x);
else
  combined_function(y);

expresiones regulares más complicados funcionarían en este caso en particular, pero he encontrado que es muy útil para poder utilizar basado en expresiones regulares de búsqueda y reemplazo, una sola vez los scripts de Perl, y el mantenimiento del código automatizado similar, por lo que prefiero un estilo de codificación que no tiene que innecesariamente complicado.

No compro en su argumento. En lo personal, yo no conozco a nadie que alguna vez haya "accidentalmente" añadió una segunda línea bajo un if. Me gustaría entender diciendo que anidados declaraciones if deberían tener los frenos para evitar un colgando más, pero como yo lo veo que están haciendo cumplir un estilo debido a un temor de que, en mi opinión, está fuera de lugar.

Aquí están las no escritas (hasta ahora supongo) reglas que pasar. Creo que ofrece la legibilidad sin sacrificar la exactitud. Se basa en la creencia de que la forma corta es en bastantes casos más legible que la forma larga.

  • Siempre use los frenos si cualquier bloque de la declaración if/else if/else tiene más de una línea. Cuenta de los comentarios, lo que significa un comentario en cualquier lugar en el medio condicionado todas las secciones del condicional usan aparatos de ortodoncia.
  • Opcionalmente utilizar llaves cuando todos bloques de la declaración son exactamente una línea.
  • Nunca coloque la sentencia condicional en la misma línea que la condición. La línea después de la sentencia if se ejecuta siempre de forma condicional.
  • Si la propia sentencia condicional realiza la acción necesaria, la forma será:

    for (init; term; totalCount++)
    {
        // Intentionally left blank
    }
    

No hay necesidad de estandarizar esto de una manera detallada, cuando se puede decir lo siguiente:

  

Nunca deje a los apoyos a cabo a expensas de la legibilidad. En caso de duda, optar por utilizar los frenos.

Creo que lo más importante acerca de los apoyos es que muy claramente expresan la intención del programador. Usted no debería tener que inferir la intención de sangría.

Una vez dicho esto, me gustan los retornos de una sola línea y continúa sugerido por Gus. La intención es obvio, y es más limpio y más fácil de leer.

Si usted tiene el tiempo para leer a través de todo esto, entonces usted tiene el tiempo para agregar las llaves adicionales.

Yo prefiero la adición de los apoyos a los condicionales de una sola línea para mantenimiento, pero puedo ver cómo hacerlo sin tirantes se ve más limpio. No me molesta, pero algunas personas podría ser apagado por el ruido visual adicional.

No puedo ofrecer un mejor argumento en contra tampoco. ¡Lo siento! ;)

En este tipo de cosas, yo recomendaría acaba de llegar a una plantilla de configuración para autoformatter de su IDE. Entonces, cada vez que sus usuarios pulsar Alt-Shift-F (o lo que sea la combinación de teclas está en su IDE de elección), se añadirán automáticamente los frenos. A continuación, sólo decir a todos: ". Seguir adelante y cambiar su color de fuente, configuración de PMD o lo que sea Por favor, no cambie las reglas de sangría o auto-Brace, aunque"

Esto toma ventaja de las herramientas a nuestro alcance para evitar discutir sobre algo que realmente no vale la pena el oxígeno que normalmente se gasta en ella.

Dependiendo en el idioma , que tiene llaves para una única sentencia condicional rayados o sentencia de bucle no es obligatorio. De hecho, me gustaría eliminarlos tener menos líneas de código.

C ++:

Version 1:

class InvalidOperation{};

//...
Divide(10, 0);
//...
Divide(int a, in b)
{
   if(b == 0 ) throw InvalidOperation();
   return a/b;
}

Versión 2:

class InvalidOperation{};

//...
Divide(10, 0);
//...
Divide(int a, in b)
{
   if(b == 0 )
   { 
      throw InvalidOperation();
   }
   return a/b;
}

C #:

Version 1:

foreach(string s in myList)
   Console.WriteLine(s);

Versión 2:

foreach(string s in myList)
{
   Console.WriteLine(s);
}

Dependiendo de su punto de vista, versión 1 ó 2 serán más legibles. La respuesta es más bien subjetiva .

Wow. NADIE es consciente de la colgando otro problema ? Esto es esencialmente LA razón para siempre el uso de llaves.

En pocas palabras, puede hacer que la lógica ambigua desagradable con else, especialmente cuando están anidados. Compiladores diferentes resolver la ambigüedad en sus propios caminos. Puede ser un gran problema para dejar fuera de los apoyos, si usted no sabe lo que está haciendo.

La estética y la legibilidad no tiene nada que hacer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top