Este capítulo describe el estilo de código fuente preferido por el equipo LinuxCNC.

1. No provoque daños

Al realizar pequeñas ediciones en el código en un estilo diferente al descrito a continuación, observe el estilo de codificación local. Cambios rápidos de un estilo de codificación a otro disminuye la legibilidad del código.

Nunca verifique el código después de ejecutar "sangría" en él. Los cambios de espacios en blanco introducidos por la sangría hacen que sea más difícil seguir el historial de revisión del archivo.

No use un editor que realice cambios innecesarios en los espacios en blanco (por ejemplo, reemplaza 8 espacios con un tabulador en una línea no modificada, o ajuste de texto en líneas no modificadas de otra manera)

2. Tabulaciones

Una tabulación siempre corresponde a 8 espacios. No escriba código que se muestra correctamente solo con una configuración de tabulación diferente.

3. Sangría

Use 4 espacios por nivel de sangría. Combinando 8 espacios en un tabulador es aceptable pero no requerido.

4. Colocación de llaves

Ponga la llave de apertura al final de la línea y la llave de cierre al principio:

if (x) {
    // hacer algo apropiado
}

La llave de cierre está en una línea propia, excepto en los casos en que sea seguida por una continuación de la misma declaración, es decir, un while en una declaración do o un else en una declaración if, así:

do {
    // algo importante
} while (x > 0);

y

if (x == y) {
    // Haz una cosa
} else if (x < y) {
    // haz otra cosa
} else {
    // hacer una tercera cosa
}

Esta colocación de llaves también minimiza el número de líneas vacías (o casi vacias), lo que permite una mayor cantidad de código o comentarios visible a la vez en un terminal de un tamaño fijo.

5. Nombrado

C es un lenguaje espartano, y así debería ser tu nombrado. A diferencia de Modula-2 y Pascal, los programadores C no usan nombres pomposos como ThisVariableIsATemporaryCounter. Un programador de C llamaría eso variable tmp, que es mucho más fácil de escribir y no mas difícil de comprender.

Sin embargo, los nombres descriptivos para las variables globales son imprescindibles. Llamar a una función global foo es un crimen.

Las variables GLOBALES (para usarlas solo si realmente se precisan) necesitan tener nombres descriptivos, al igual que las funciones globales. Si tiene una función que cuenta el número de usuarios activos, debe llame a eso count_active_users() o similar, no debe llamarla cntusr().

Codificar el tipo de una función en el nombre (llamada notación húngara) no tiene sentido; el compilador conoce los tipos de todos modos y puede verificarlos, y solo confunde al programador. No es de extrañar que Microsoft haga programas con errores.

Los nombres de variables LOCALES deben ser cortos y escuetos. Si usted tiene algún contador entero de bucles aleatorio, probablemente debería llamarse i. Llamarlo loop_counter no es productivo, si no hay posibilidad de ser mal entendido. Del mismo modo, tmp puede ser casi cualquier tipo de variable que se utiliza para mantener un valor temporal.

Si tiene miedo de mezclar sus nombres de variables locales, tiene otro problema, que se llama síndrome de desequilibrio de la hormona del crecimiento funcional. Ver el siguiente capítulo.

6. Funciones

Las funciones deben ser cortas y fáciles, y hacer una sola cosa. Deben caber en una o dos pantallas de texto (el tamaño de pantalla ISO/ANSI es 80x24, como todos sabemos), hacer una cosa y hacerla bien.

La longitud máxima de una función es inversamente proporcional a la complejidad y nivel de sangría de esa función. Por tanto, si tiene una función conceptualmente simple que es solo un largo (pero simple) switch-case, donde tienes que hacer muchas cosas pequeñas para muchos casos diferentes, está bien tener una función más larga.

Sin embargo, si tiene una función compleja y sospecha que un estudiante de primer año de secundaria no superdotado no podría siquiera entender de qué se trata la función, debe respetar los límites máximos más de cerca. Use funciones de ayuda con nombres descriptivos (puede pedirle al compilador que los incorpore si piensa que es crítico para el rendimiento, y probablemente hará un mejor trabajo que el suyo).

Otra medida de la función es el número de variables locales. No deben exceder de 5-10, o algo estás haciendo mal. Repensar la función, y dividirla en pedazos más pequeños. Un cerebro humano generalmente puede realizar un seguimiento de aproximadamente 7 cosas diferentes, cualquier cosa más y se confunde. Sabes que eres brillante, pero tal vez te gustaría entender lo que hiciste dentro de 2 semanas.

7. Comentarios

Los comentarios son buenos, pero también existe el peligro de comentar en exceso. NUNCA intente explicar CÓMO funciona su código en un comentario; es mucho mejor escribir el código para que el funcionamiento sea obvio, y es un desperdicio de tiempo explicar un código mal escrito.

En general, busque que sus comentarios digan QUÉ hace su código, no CÓMO. Un comentario en recuadro que describe la función, el valor de retorno y quién lo llama colocado encima del cuerpo es bueno. Además, trate de evitar poner comentarios dentro del cuerpo de una función; si la función es tan compleja que necesita comentar partes por separado, probablemente debería volver a leer la sección de funciones de nuevo. Puede hacer pequeños comentarios para anotar o advertir sobre algo particularmente inteligente (o feo), pero trate de evitar el exceso. En su lugar, coloque los comentarios al frente de la función, diciéndoles a las personas lo que hace, y posiblemente POR QUÉ lo hace.

Si se utilizan comentarios /* Fix me */ en la línea, por favor, por favor, decir por qué algo necesita ser reparado. Cuando se ha realizado un cambio en la parte afectada del código, elimine el comentario o modifíquelo para indicar que se ha realizado un cambio y necesita pruebas.

8. Scripts de Shell y Makefiles

No todos tienen las mismas herramientas y paquetes instalados. Algunas personas usan vi, otros emacs: algunos incluso evitan tener cualquiera de estos paquetes instalados, prefiriendo un editor de texto liviano como nano o el construido en Midnight Commander.

gawk versus mawk - Nuevamente, no todos tendrán gawk instalado, mawk es casi una décima parte del tamaño y, sin embargo, se ajusta al Posix AWK estándar. Si se necesita algún comando específico de gawk oscuro que mawk no proporciona, el script se romperá para algunos usuarios. Lo mismo se aplicaría a mawk. En resumen, use la invocación genérica awk en preferencia a gawk o mawk.

9. Convenciones de C++

Los estilos de codificación de C++ siempre terminan en acalorados debates (un poco como los argumentos de emacs versus vi). Una cosa es cierta, sin embargo; el estilo común utilizado por todos los que trabajan en un proyecto conduce a la uniformidad y a código legible

Convenciones de nomenclatura: las constantes #define o enumeraciones debe estar en mayúscula. Justificación: hace que sea más fácil detectar constantes de tiempo de compilación en el código fuente. p.ej. EMC_MESSAGE_TYPE

Las clases y los espacios de nombres deben poner en mayúscula la primera letra de cada palabra y evitar guiones bajos. Justificación: identifica clases, constructores y destructores. p.ej. GtkWidget

Los métodos (o nombres de funciones) deben seguir las recomendaciones C anteriores y no debe incluir el nombre de la clase. Justificación: mantiene un estilo común en fuentes C y C++. p.ej. get_foo_bar()

Sin embargo, los métodos booleanos son más fáciles de leer si evita los guiones bajos y use un prefijo is (no debe confundirse con los métodos que manipulan un booleano). Justificación: identifica el valor de retorno como VERDADERO o FALSO y nada más. p.ej. isOpen, isHomed

NO use Not en un nombre booleano, solo conduce a confusión al hacer pruebas lógicas. p.ej. isNotOnLimit o is_not_on_limit son MALOS.

Los nombres de las variables deben evitar el uso de mayúsculas y guiones bajos a excepción de nombres locales o privados. El uso de variables globales debería evitarse tanto como sea posible. Justificación: aclara cuáles son variables y cuales son métodos. Ej. Público: axislimit. Ej. Privado: maxvelocity_

Convenciones de nomenclatura de métodos específicos

Los términos get y set deben usarse donde se accede a un atributo directamente. Justificación: indica el propósito de la función o método. p.ej. get_foo set_bar

Para los métodos que involucran atributos booleanos, se prefiere set y reset. Justificación: como arriba. p.ej. set_amp_enable reset_amp_fault

Los métodos intensivos en matemáticas deben usar el cálculo como prefijo. Razón fundamental: mostrar que es computacionalmente intensivo y acaparará la CPU. p.ej. compute_PID

Las abreviaturas en los nombres deben evitarse siempre que sea posible. la excepción es para nombres de variables locales. Justificación: claridad del código. p.ej. se prefiere pointer a ptr, compute a cmp, o compare a (de nuevo) cmp.

Las enumeraciones y otras constantes pueden tener como prefijo un nombre de tipo común p.ej. enum COLOR{COLOR_RED, COLOR_BLUE};

Se debe evitar el uso excesivo de macros y defines. Se prefieren métodos o funciones. Justificación: mejora el proceso de depuración.

Los declaraciones include de archivos de encabezado deben incluirse en la parte superior de un archivo fuente y no disperso por todo el cuerpo. Deberían estar ordenados y agrupados por su posición jerárquica dentro del sistema con los archivos de bajo nivel incluidos primero. Las rutas de archivos include NUNCA deben ser absolutas; use el flag del compilador -I en su lugar. Razón fundamental: Los encabezados pueden no estar en el mismo lugar en todos los sistemas.

Los punteros y las referencias deben tener su símbolo de referencia junto al nombre de la variable y no junto al nombre del tipo. Justificación: Reduce la confusión. p.ej. float *x o int &i

Las pruebas implícitas para cero no deben usarse excepto para variables booleanas. p.ej. if (spindle_speed != 0) NO if (spindle_speed)

Solo las declaraciones de control de bucle deben incluirse en una construcción for(). p.ej. sum = 0; for (i = 0; i < 10; i++) { sum += value[i]; }

NO for (i = 0, sum =0; i < 10; i++) sum += value[i];

Del mismo modo, deben evitarse las declaraciones ejecutables en condicionales. p.ej. if (fd = open(nombre_archivo) es malo.

Deben evitarse las declaraciones condicionales complejas - Introducir variables booleanas temporales en su lugar.

Los paréntesis deben usarse en abundancia en las expresiones matemáticas. No confíe en la precedencia del operador cuando un paréntesis adicional aclararía las cosas.

Nombres de archivo: las fuentes y los encabezados de C++ usan la extensión .cc y .hh. El uso de .c y .h están reservados para C. Los encabezados son para clases, métodos, y declaraciones de estructuras, no para código (a menos que se declaren las funciones inline).

10. Estándares de codificación de Python

Utilice el estilo PEP 8 para Código de Python

11. Estándares de codificación comp

En la parte de declaración de un archivo .comp, comience cada declaración en la primera columna. Insertar líneas en blanco adicionales cuando ayuden a agrupar items relacionados.

En la parte del código de un archivo .comp, siga el estilo de codificación C normal.