Estás leyendo la documentación para una versión de desarrollo. Para la última versión publicada, por favor revisa Humble.
Estilo de código y versiones de lenguaje
Tabla de Contenido
Para lograr un producto de apariencia consistente, todos seguiremos para cada lenguaje de programación guías de estilo (de ser posible) que ya estén definidas externamente. Para otras cosas, como el diseño de paquetes o el diseño de la documentación, necesitaremos crear nuestras propias pautas, basándonos en los estilos actuales y populares que se usan ahora.
Además, siempre que sea posible, los desarrolladores deben usar herramientas integradas que les permitan verificar que se sigan estas pautas en sus editores. Por ejemplo, todos deberían tener un verificador PEP8 integrado en su editor para reducir las iteraciones de revisión relacionadas con el estilo.
Además, cuando sea posible, los paquetes deben verificar el estilo como parte de sus pruebas unitarias para ayudar con la detección automática de problemas de estilo (ver ament_lint_auto).
C
Estilo
Usaremos Python’s PEP7 para nuestra guía de estilo C, con algunas modificaciones y adiciones:
Apuntamos a C99, ya que no necesitamos admitir C89 (como recomienda PEP7)
justificación: entre otras cosas, nos permite usar comentarios de estilo
//
y/* */
justificación: C99 es bastante omnipresente ahora
Se permiten comentarios estilo C++
//
(opcional) Coloque siempre los literales en el lado izquierdo de los operadores de comparación, por ejemplo,
0 == ret
en lugar deret == 0
justificación:
ret == 0
puede convertirse en fácilmenteret = 0
por accidenteopcional porque al usar
-Wall
(o equivalente) los compiladores modernos le avisarán cuando esto suceda
Todas las siguientes modificaciones solo se aplican si no se esta escribiendo módulos de Python:
No use
Py_
como prefijo para todoen su lugar, use una versión CamelCase del nombre del paquete u otro prefijo apropiado
las cosas sobre documentación de strings no se aplica
Podemos usar el módulo de python pep7 para verificación de estilo. La integración del editor parece escasa, es posible que debamos analizar la verificación automática de C con más detalle.
C++
Estilo
Usaremos la Guía de estilo de Google C++ Style Guide, con algunas modificaciones:
Longitud de la línea
Nuestra longitud máxima de línea es de 100 caracteres.
Extensiones de archivo
Los archivos de encabezado deben usar la extensión .hpp.
justificación: permitir que las herramientas determinen el contenido de los archivos, C++ o C.
Los archivos de implementación deben usar la extensión .cpp.
justificación: permitir que las herramientas determinen el contenido de los archivos, C++ o C.
Nomenclatura de variables
Para variables globales, use minúsculas con guiones bajos con el prefijo
g_
justificación: mantener la coherencia entre mayúsculas y minúsculas en todo el proyecto
justificación: es fácil saber el alcance de una variable de un vistazo
coherencia entre lenguajes
Denominación de funciones y métodos
La guía de estilo de Google dice
CamelCase
, pero también se permite el estilosnake_case
de la biblioteca estándar de C++justificación: los paquetes principales de ROS 2 actualmente usan
snake_case
razón: ya sea un descuido histórico o una preferencia personal que no fue verificada por el linter
razón para no cambiar: cambiar retroactivamente sería demasiado disruptivo
Otras Consideraciones:
cpplint.py
no verifica este caso (difícil de hacer cumplir excepto con revisión)snake_case
puede dar como resultado una mayor coherencia entre lenguajes
orientación específica:
para proyectos existentes, se prefiere el estilo existente
para nuevos proyectos, cualquiera de los dos es aceptable, pero se recomienda una preferencia por la coincidencia de proyectos existentes relacionados
la decisión final es siempre discreción del desarrollador
casos especiales como punteros de función, tipos invocables, etc. pueden requerir doblar las reglas
Tenga en cuenta que las clases aún deben usar
CamelCase
por defecto
Control de acceso
Elimina el requisito de que todos los miembros de la clase sean privados y, por lo tanto, requieran accessors
justificación: esto es demasiado restrictivo para el diseño de API de usuario
debemos preferir miembros privados, solo haciéndolos públicos cuando sean necesarios
debemos considerar el uso de accessors antes de elegir permitir el acceso directo a los miembros
debemos tener una buena razón para permitir el acceso directo de los miembros, que sea conveniente para nosotros no es razón suficiente.
Excepciones
Se permiten excepciones
justificación: esta es una nueva base de código, por lo que el argumento heredado no se aplica a nosotros
justificación: para las API orientadas al usuario, es más idiomático C++ tener excepciones
Las excepciones en los destructores deben evitarse explícitamente
Debemos considerar evitar Excepciones si tenemos la intención de envolver la API resultante en C
justificación: hará que sea más fácil envolver en C
justificación: la mayoría de nuestras dependencias en el código que pretendemos envolver en C no usan excepciones de todos modos
Objetos similares a funciones
Sin restricciones en Lambda’s o
std::function
ostd::bind
Boost
Boost debe evitarse a menos que sea absolutamente necesario.
Comentarios y comentarios del documento
Utilice los comentarios
///
y/** */
para propósitos de documentación y comentarios de estilo//
para notas y comentarios generalesLos comentarios de clase y función deben usar comentarios de estilo
///
y/** */
justificación: se recomiendan para Doxygen y Sphinx en C/C++
justificación: mezclar
/* */
y//
es conveniente para comentar bloques de código que contengan comentariosLas descripciones de cómo funciona el código o las notas dentro de las clases y funciones deben usar comentarios de estilo
//
Alineación de sintaxis de puntero
Use
char * c;
en lugar dechar* c;
ochar *c;
debido a este escenariochar* c, *d, *e;
Palabras clave de privacidad de clase
No coloque 1 espacio antes de
public:
,private:
oprotected:
, es más consistente que todas las sangrías sean múltiplos de 2justificación: a la mayoría de los editores no les gustan las sangrías que no son un múltiplo del tamaño de la pestaña (suave)
Usa cero espacios antes de
public:
,private:
, oprotected:
, o 2 espaciosSi usa 2 espacios antes, indenta otras declaraciones de clase con 2 espacios adicionales
Se prefiere cero espacios, es decir,
public:
,private:
oprotected:
en la misma columna que la clase
Plantillas anidadas
Nunca agregue espacios en blanco a las plantillas anidadas
Se prefiere
set<list<string>>
(característica de C++11 ) aset<list<string> >
oset< list<string> >
Paréntesis abiertos Versus Cuddled
Usa paréntesis en una nueva linea para
function
,class
,enum
, ystruct
, pero paréntesis en la misma linea paraif
,else
,while
,for
, etc…Excepción: cuando un
if
(owhile
, etc.) es lo suficiente largo que no quepa en linea, entonces usar nueva linea (i.e., don’t cuddle).
Cuando una llamada a una función no quepa en una linea, rompe la linea (no entre argumentos) y empieza en la proxima linea con indentación de 2 espacios. Si se tienen más argumentos continua con la indentación de 2 espacios en las lineas siguientes . (Nota que la Guía de estilos de Google se autocontradice en este punto.)
Lo mismo se aplica a
if
(ywhile
, etc.) si son demasiado largas para caber en una linea.
Ejemplos
Esto esta OK:
int main(int argc, char **argv)
{
if (condition) {
return 0;
} else {
return 1;
}
}
if (this && that || both) {
...
}
// Long condition; open brace
if (
this && that || both && this && that || both && this && that || both && this && that)
{
...
}
// Short function call
call_func(foo, bar);
// Long function call; wrap at the open parenthesis
call_func(
foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar,
foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar, foo, bar);
// Very long function argument; separate it for readability
call_func(
bang,
fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo,
bar, bat);
Esto no esta bien:
int main(int argc, char **argv) {
return 0;
}
if (this &&
that ||
both) {
...
}
Usa corchetes abierto en lugar de usar sangria de manera excesiva, p.ej. para distinguir el código del constructor de las listas de inicializadores del constructor
Esto esta OK:
ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
Type par_name1, // 2 space indent
Type par_name2,
Type par_name3)
{
DoSomething(); // 2 space indent
...
}
MyClass::MyClass(int var)
: some_var_(var),
some_other_var_(var + 1)
{
...
DoSomething();
...
}
Esto no está bien, incluso es extraño (¿a la manera de Google?):
ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
Type par_name1, // 4 space indent
Type par_name2,
Type par_name3) {
DoSomething(); // 2 space indent
...
}
MyClass::MyClass(int var)
: some_var_(var), // 4 space indent
some_other_var_(var + 1) { // lined up
...
DoSomething();
...
}
Linters
El estilo fue verificado con una combinación de cpplint.py de Google y uncrustify.
Proporcionamos herramientas de linea de comandos con las configuraciones personalizada:
Algunos correctores de estilo como ament_uncrustify y ament_clang_format tienen la opción --reformat
para aplicar los cambios.
También ejecutamos otras herramientas para detectar y eliminar tantas advertencias como sea posible. Aquí hay una lista no exhaustiva de cosas adicionales que tratamos de hacer en todos nuestros paquetes:
usar banderas del compilador como
-Wall -Wextra -Wpedantic
ejecutar análisis de código estático como
cppcheck
, que hemos integrado en ament_cppcheck.
Python
Estilo
Usaremos las directrices de PEP8 para el formato del código.
Elegimos la siguiente regla más precisa donde PEP 8 deja cierta libertad:
Elegimos comillas simples sobre comillas dobles siempre que no sea necesario escapar.
Preferimos sangrías colgantes para las líneas de continuación.
Las herramientas como el paquete de Python (ament_)pycodestyle
deben usarse en la integración de pruebas unitarias y/o editores para comprobar el estilo del código de Python.
La configuración de pycodestyle utilizada en el linter está aquí.
Integración con editores:
CMake
Estilo
Dado que no existe una guía de estilo de CMake, definiremos la nuestra:
Usa nombres de comando en minúsculas (
find_package
, noFIND_PACKAGE
).Usa identificadores
snake_case
(variables, funciones, macros).Utiliza los comandos vacíos
else()
yend...()
.Sin espacios en blanco antes de
(
“s.Usa dos espacios de sangría, no use tabulaciones.
No uses sangría alineada para parámetros de invocaciones de macros de varias líneas. Use dos espacios solamente.
Se Preferiré funciones con
set(PARENT_SCOPE)
a macros.Al usar macros prefija las variables locales con
_
o un prefijo razonable.
Markdown / reStructured Text / docblocks
Estilo
Las siguientes reglas para dar formato al texto están destinadas a aumentar la legibilidad, así como el control de versiones.
[.md, .rst solamente] Cada título de sección debe estar precedido por una línea vacía y seguido por una línea vacía.
Justificación: Es rápido obtener una visión general de la estructura al examinar el documento.
[Solo .rst] En el texto reStructured, los encabezados deben seguir la jerarquía descrita en la guía de estilo de Sphinx:
#
con línea superior (solo una vez, se usa para el título del documento)*
con sobrelínea=
-
^
"
Justificación: una jerarquía coherente acelera la obtención de una idea sobre el nivel de anidamiento al examinar el documento.
[Solo .md] En Markdown, los encabezados deben seguir el estilo ATX descrito en la documentación de sintaxis de Markdown
Los encabezados de estilo ATX usan de 1 a 6 caracteres hash (
#
) al comienzo de la línea para indicar los niveles de encabezado 1-6.Se debe usar un espacio entre los hash y el título del encabezado (como
# Heading 1
) para que sea más fácil separarlos visualmente.La justificación de la preferencia del estilo ATX proviene de la guía de estilo de Google Markdown
Justificación: los encabezados de estilo ATX son más fáciles de buscar y mantener, y hacen que los dos primeros niveles de encabezado sean coherentes con los otros niveles.
[cualquiera] Cada oración debe comenzar en una nueva línea.
Justificación: para párrafos más largos, un solo cambio al principio hace que la diferencia sea ilegible, ya que continúa a lo largo de todo el párrafo.
[cualquiera] Opcionalmente, cada oración se puede envolver para que cada línea sea corta.
[cualquiera] Las líneas no deben tener ningún espacio en blanco al final.
[.md, .rst solamente] Un bloque de código debe estar precedido y seguido por una línea vacía.
Justificación: los espacios en blanco son significativos solo directamente antes y después de los bloques de código delimitados. Seguir estas instrucciones asegurará que el resaltado funcione de manera adecuada y consistente.
[.md, .rst solamente] Un bloque de código debe especificar una sintaxis (por ejemplo,
bash
).