Regla 0x010Dh: Auditor de consistencia en nombres de constantes simbólicas
Nomenclatura e identificadores (0x01XX)
0x010Dh: Auditor de consistencia en nombres de constantes simbólicas¶
Enunciado normativo¶
Toda constante simbólica declarada con
#defineDEBE nombrarse íntegramente en mayúsculas sostenidas con guiones bajos (SCREAMING_SNAKE_CASE):BUFFER_SIZE, nobuffer_sizeniMax_Len.
¿Por qué existe esta regla?¶
El problema¶
Una macro del preprocesador no es una variable ni una función: es una
sustitución textual que ocurre antes de compilar. Si su nombre se parece al de
una variable (buffer_size) o de una función (calcular_total), el lector no
puede saber, sólo mirando el identificador, si hay una llamada real, una lectura
de memoria o una simple expansión de texto. La convención de mayúsculas
sostenidas actúa como señal visual de inmutabilidad y de origen
preprocesador, y esa distinción es crítica cuando la macro recibe argumentos,
porque entonces puede evaluar sus expresiones más de una vez.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| Bug silencioso | Una macro con nombre de función se invoca como si fuera una y se pasan argumentos con efectos laterales que se evalúan dos veces. |
| Legibilidad | No se distingue a simple vista una constante simbólica de una variable. |
| Mantenibilidad | Al cambiar la macro por una función (o al revés) el nombre deja de ser coherente. |
| Revisión | gaff reporta la inconsistencia de SCREAMING_SNAKE_CASE. |
Fundamento en el estándar y en la cátedra¶
ISO/IEC 9899:2011 §6.10.3 (Macro replacement) define la semántica textual del
preprocesador; de ahí la necesidad de distinguir visualmente las macros del
resto de los identificadores. La cátedra fija SCREAMING_SNAKE_CASE como
convención institucional y la articula con 0x0107h: Las macros #define deben nombrarse en MAYUSCULAS_SNAKE_CASE, que cubre todas las
macros, y con 0x0103h: Las constantes (const o #define) deben nombrarse en MAYUSCULAS_SNAKE_CASE, que alcanza también a las constantes const. Esta
regla enfatiza la consistencia: la misma constante no debe aparecer escrita
de dos formas en el mismo proyecto.
Alcance y excepciones¶
Aplica a todas las constantes simbólicas creadas con #define, incluidas las
macros con parámetros y las guardas de inclusión. No aplica a los nombres de
funciones (0x0105h: Los nombres de funciones deben usar snake_case estricto en minúsculas) ni a los tipos (0x3004h: Utilizá typedef para definir tipos de estructuras con el sufijo _t), que usan otras
convenciones. Las constantes definidas con const también van en mayúsculas por
0x0103h: Las constantes (const o #define) deben nombrarse en MAYUSCULAS_SNAKE_CASE, pero suelen escribirse en minúsculas si el proyecto las trata
como objetos; lo que la regla prohíbe es mezclar estilos dentro del mismo
archivo.
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — Minaúsculas y caso mixto¶
#define buffer_size 1024
#define Max_Len 256
#define totalIntentos 5Por qué falla: los tres nombres parecen variables. Max_Len mezcla PascalCase y
snake_case; totalIntentos usa camelCase; ninguno advierte que son
sustituciones textuales.
❌ Contraejemplo 2 — Macro con parámetros en minúscula¶
#define cuadrado(x) ((x) * (x))Por qué falla: el nombre de función en minúsculas invita a usarla como tal. Si
se invoca cuadrado(i++), el argumento se expande dos veces y el incremento
ocurre dos veces, un bug clásico de macros con argumentos.
✅ Ejemplo conforme 1 — Constantes canónicas¶
#define BUFFER_SIZE 1024
#define MAX_LEN 256
#define TOTAL_INTENTOS 5Por qué cumple: todo el nombre en mayúsculas con guiones bajos; la forma avisa de inmediato que se trata de una constante simbólica y no de una variable.
✅ Ejemplo conforme 2 — Macro funcional e interacción con protección¶
#define CUADRADO(x) ((x) * (x))
#define ES_PAR(n) (((n) % 2) == 0)Por qué cumple: el nombre va en mayúsculas, los parámetros se encierran entre paréntesis conforme a 0x500Ah: Protección obligatoria de parámetros en macros funcionales mediante paréntesis y el cuerpo entero se protege con paréntesis según 0x5013h: Protección obligatoria con paréntesis envolventes en expresiones de macroconstantes (#define), evitando sorpresas de precedencia.
⚠️ Casos límite¶
Guardas de inclusión: también mayúsculas, con el nombre del módulo (0x5003h: Utilizá guardas de inclusión en todos los archivos de cabecera).
Macros que reflejan funciones de la biblioteca: no redefinir nombres estándar; ver 0x500Dh: Prohibición de redefinir palabras clave o tipos primitivos de C con #define.
Constantes
enum: suelen ir en mayúsculas como constantes simbólicas; ver 0x300Dh: Utilizá enum en lugar de ‘números mágicos’ para conjuntos de estados y valores constantes.Macros de una sola letra: prohibidas por opacas y por colisionar con variables.
Redefinición: una macro no debe cambiar de nombre ni de valor sin actualizar todos los usos.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | Reporta #define cuyo nombre no está en SCREAMING_SNAKE_CASE. |
gcc / clang | gcc -Wall -Wextra -Wpedantic -std=c11 -c archivo.c | No reporta: es una regla de nomenclatura. |
| Revisión manual | — | Buscar #define con minúsculas o caso mixto. |
Checklist de autocontrol¶
Toda macro mía está íntegramente en mayúsculas con guiones bajos.
No mezclé
PascalCase,camelCasenilower_snakeen constantes.Las macros con parámetros también van en mayúsculas.
Protegí el cuerpo y los parámetros con paréntesis (0x5013h: Protección obligatoria con paréntesis envolventes en expresiones de macroconstantes (#define), 0x500Ah: Protección obligatoria de parámetros en macros funcionales mediante paréntesis).
Las guardas de inclusión usan el nombre del módulo (0x5003h: Utilizá guardas de inclusión en todos los archivos de cabecera).
Reglas relacionadas¶
0x0107h: Las macros #define deben nombrarse en MAYUSCULAS_SNAKE_CASE — todas las macros
#defineen mayúsculas sostenidas.0x0103h: Las constantes (const o #define) deben nombrarse en MAYUSCULAS_SNAKE_CASE — constantes
consty#defineen mayúsculas.0x5013h: Protección obligatoria con paréntesis envolventes en expresiones de macroconstantes (#define) — paréntesis protectores en expresiones de macro.
0x500Ah: Protección obligatoria de parámetros en macros funcionales mediante paréntesis — paréntesis protectores en parámetros de macro.
0x5003h: Utilizá guardas de inclusión en todos los archivos de cabecera — guardas de inclusión.