Regla 0x0005h: El asterisco de los punteros debe declararse junto al identificador
Sintaxis y formato visual (0x00XX)
0x0005h: El asterisco de los punteros debe declararse junto al identificador¶
Enunciado normativo¶
DEBE escribirse el asterisco de un puntero adherido al identificador (
int *ptr), con un espacio entre el tipo y el asterisco. NO DEBE pegarse el asterisco al tipo (int* ptr).
La forma elegida refleja que * modifica al declarador, no al tipo base.
¿Por qué existe esta regla?¶
El problema¶
En C la declaración se lee siguiendo los declaradores (§6.7.6): el * forma
parte del nombre declarado, no del tipo. Escribir int* ptr sugiere que
int* es un tipo atómico, lo que es falso en listas múltiples: en
int* a, b; solo a es puntero y b es un int. La forma int *a, b;
hace evidente que el asterisco pertenece a a.
Además, la convención unifica la lectura con el operador de
desreferenciación, que se escribe igual: *ptr.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| Compilación | Ninguna por sí sola; el error aparece en declaraciones múltiples. |
| Bug silencioso | int* a, b; hace creer que b es puntero y provoca usos incorrectos. |
| Legibilidad | Se pierde la pista visual de qué declaradores son punteros. |
| Consistencia | Convive con *ptr de desreferencia y confunde el criterio. |
| Refactorización | Mover * de un lado a otro rompe el estilo del archivo. |
Fundamento en el estándar y en la cátedra¶
El estándar define los declaradores con una gramática recursiva en la que
* precede al identificador (§6.7.6). La cátedra adopta tipo *id porque
coincide con esa lectura y porque evita el malentendido de tipos atómicos
inexistentes.
Alcance y excepciones¶
Aplica a toda declaración de puntero: variables, parámetros, campos de struct, valores de retorno y typedefs. En los tipos de puntero a función la convención se combina con 0x0012h: Validador de formato canónico en firmas de punteros a función; en punteros múltiples, con 0x0009h: Espaciado consistente en declaraciones de doble puntero (tipo **var).
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — Asterisco pegado al tipo¶
int* ptr;Por qué falla: induce a creer que int* es un tipo; al leer
int* ptr, contador; se asume erróneamente que contador también apunta.
❌ Contraejemplo 2 — Lista mixta con asterisco a la izquierda¶
char* nombre, apellido;Por qué falla: apellido es un char, no un char *; la forma induce al
error de asignarle después una cadena mediante strcpy(apellido, ...).
✅ Ejemplo conforme 1 — Asterisco junto al nombre¶
int *ptr;
char *nombre;
struct nodo_t *siguiente;Justificación: el asterisco se lee como parte del declarador y cada identificador revela de inmediato si es puntero.
✅ Ejemplo conforme 2 — Lista explícita de punteros¶
int *inicio;
int *fin;
int contador;Justificación: al declarar cada variable en su línea (0x0002h: Una declaración de variable por línea) la ambigüedad desaparece y el tipo de cada una queda a la vista.
⚠️ Casos límite¶
Cast explícito: en
(int *)pel asterisco va junto al tipo porque es una conversión, no una declaración.Valor de retorno:
char *leer_linea(void);sigue la misma convención.const: enint * const pelconstcalifica al puntero, no al dato; el asterisco permanece junto ap.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c / gaff fix archivo.c | Asterisco adherido al tipo base. |
gcc / clang | gcc -Wall -Wextra -std=c11 | -Wpointer-sign o -Wincompatible-pointer-types al usar mal la variable. |
| Revisión manual | — | Comparar con la forma tipo *id. |
Checklist de autocontrol¶
¿Escribí
int *ptry noint* ptr?¿Declaré cada puntero en su propia línea?
¿Revisé que todas las variables de una lista sean del tipo esperado?
¿Apliqué la misma convención en parámetros y retornos?
Reglas relacionadas¶
0x0009h: Espaciado consistente en declaraciones de doble puntero (tipo **var) — espaciado de los asteriscos en doble puntero.
0x0012h: Validador de formato canónico en firmas de punteros a función — formato canónico de punteros a función.
0x0002h: Una declaración de variable por línea — una declaración por línea evita el error de lista mixta.
0x3005h: Minimizá el uso de múltiples niveles de indirección (punteros a punteros) — minimizar los niveles de indirección.
0x300Ah: Utilizá cast explícito al convertir tipos de punteros — conversiones de puntero siempre explícitas.