#Sobre las barras bajas iniciales y otras "convenciones" muy extendidas en C/C++

| 4 MIN DE LECTURA
Muy pronto...

Este es uno de esos posts que se actualizan de vez en cuando, y lo haré cada vez que me encuentre con una nueva “convención”.

Sé que el título en español es criminal, y nadita que ver con su homólogo en inglés. Pero es lo que hay. Bastante me ha costado a mí asumirlo :^).

Ha pasado más de un mes desde mi último post… pero he vuelto .

La verdad es que esto de escribir un blog, aunque sobre todo el sacar temas, es muy, muy difícil. Eso, sumado a que soy nuevo tanto en el mundo del malware como en esto (escribiendo), no ayuda… El otro día estaba hablando justo de esto con un compañero, concretamente sobre las expectativas y el listón tan alto que a veces (o casi siempre) nos ponemos a nosotros mismos, y me dijo algo que me hizo clic (no con estas palabras exactas, pero casi): “No hay que intentar anticipar lo que creemos que le va a gustar o no a la gente, escribe algo y ya!”.

Y a ver, razón no le falta. No hay necesidad alguna de encontrar el tema “perfecto”. Ni siquiera hace falta intentar buscar algo que creamos que le vaya a poder gustar o interesar a la gente. Es imposible anticipar eso. De hecho, si pudiéramos, ya te digo yo que tardaría entre poco y nada en ponerme a tirar las cartas…

Y es que a veces, hasta los temas más “simples” o comunes, son suficientes, siempre y cuando estén bien presentados por supuesto. Internet está plagado de contenido mediocre (por desgracia), y hoy en día, con el auge de la IA, todavía más. Mi objetivo, tal y como comento en “ Sobre Mí ENLACE EXTERNO A:

https://allthingsmalware.com/es/about/
”, es crear contenido que sea lo suficientemente interesante como para que la gente lo lea y lo use en sus propias mierdas. Con suerte, este post es justamente eso.

Después de esta chapa , vamos al lío.

Una “convención” bastante común en los headers que he visto por todos los lados (Stack Overflow, clases de la uni, GitHub, etc.) es _NOMBRE_DEL_HEADER_H_. Esto, junto con las include guards ENLACE EXTERNO A:

https://en.wikipedia.org/wiki/Include_guard
de C/C++, evita que la misma cabecera se incluya varias veces al compilar, es decir, esto1:

Cabeceras sin include guards
Cabeceras sin include guards

Sin embargo, esta “convención” está mal, y seguro que esto le pilla a más de uno por sorpresa.

Los requisitos de implementación de C++ ENLACE EXTERNO A:

https://timsong-cpp.github.io/cppwp/lex.name#3
especifican las reglas para determinar si un identificador está reservado para uso del lenguaje o no. La sección 7.1.3 de C11 ENLACE EXTERNO A:

https://port70.net/~nsz/c/c11/n1570.html#7.1.3
contiene las reglas para C, que son prácticamente las mismas (sorpresa). Y basándonos en eso, nos podemos montar la siguiente tabla2:

PatrónCondicionesEjemplo
Empieza con dos guiones bajosReservado__MI_HEADER_H__
Empieza con guión bajo y letra mayúsculaReservado_MI_HEADER_H_
Empieza con guión bajo y cualquier otra cosaReservado en el ámbito global (incluye macros)_ejemplo
Contiene dos guiones bajos consecutivosReservado en C++ (pero válido en C)ejen__plo

Y ojo, que estos ejemplos se aplican a todo, no solo a los headers.

Header Guards

Por tanto, para los header guards, el fix es muy sencillo: quitar los guiones bajos del principio y del final.

Incorrecto:

Toggle Line Numbers
Copy Code
1
2
3
4
5
6
#ifndef _MI_HEADER_H_
#define _MI_HEADER_H_

...

#endif // _MI_HEADER_H_

Correcto:

Toggle Line Numbers
Copy Code
1
2
3
4
5
6
#ifndef MI_HEADER_H
#define MI_HEADER_H

...

#endif // MI_HEADER_H

Funciones (o variables) privadas

Como ya te puedes imaginar a estas alturas, hay otra convención errónea bastante popular: cascarle un guión bajo por delante del nombre a las funciones (o variables) privadas.

En su lugar, lo que se debería usar (y ojo que aquí hablo solo de funciones) es la keyword static, que limita el alcance de la función al fichero donde está definida. En la práctica, esto hace que el símbolo no sea visible desde fuera, lo que nos permite definir una función privada para que:

  1. Podamos tener dos funciones estáticas con el mismo nombre en ficheros distintos sin que haya colisiones de nombres.
  2. Podamos definir funciones auxiliares (helpers) o internas pensadas para uso propio que no se puedan llamar fuera de donde toca.

Incorrecto:

Toggle Line Numbers
Copy Code
1
2
3
4
int _x;
void _miFuncionPrivada(void) {
    ...
}

Correcto:

Toggle Line Numbers
Copy Code
1
2
3
4
int x;
static void miFuncionPrivada(void) {
    ...
}

Sed buenos!