Regla 0x3004h: Utilizá typedef para definir tipos de estructuras con el sufijo _t
Memoria, punteros y tipos (0x30XX)
0x3004h: Utilizá typedef para definir tipos de estructuras con el sufijo _t¶
Enunciado normativo¶
DEBE declararse un alias con
typedefpara cadastruct,enumounionque se use como tipo, y el alias DEBE terminar en el sufijo_t(nodo_t,lista_t,estado_t). El alias DEBE escribirse ensnake_caseminúsculo.
¿Por qué existe esta regla?¶
El problema¶
En C, la etiqueta de un struct y un nombre de tipo viven en espacios de nombres
distintos. Declarar struct nodo { int dato; }; no crea un tipo llamado nodo:
obliga a escribir struct nodo cada vez, ensucia las firmas y abre la puerta a
olvidar la palabra clave. El typedef crea un alias en el espacio de nombres de
tipos, y el sufijo _t señala de un vistazo que se trata de un tipo.
Consecuencias de violarla¶
| Tipo de consecuencia | Efecto concreto |
|---|---|
| Ruido sintáctico | Cada uso repite struct, sobre todo en punteros y arreglos. |
| Ambigüedad visual | nodo puede parecer una variable compartida en el código. |
| Inconsistencia | Conviven Nodo, nodo, struct nodo para el mismo concepto. |
Fundamento en el estándar y en la cátedra¶
C11 §6.7.8 define typedef como declaración de un alias de tipo. La cátedra
adopta el sufijo _t como convención institucional, tanto para tipos públicos
como internos. La biblioteca reserva algunos nombres con ese sufijo (size_t,
time_t), pero el espacio del usuario es distinto.
Alcance y excepciones¶
Aplica a struct, enum y union usados como tipo, incluidos los tipos
opacos. No aplica a alias de tipos básicos que oscurecen el significado
(typedef int boom_t;); la cátedra desaconseja esos alias. Tampoco exige
typedef en etiquetas que nunca se usan como tipo, aunque en la práctica toda
etiqueta termina siéndolo.
Ejemplos exhaustivos¶
❌ Contraejemplo 1 — Alias en PascalCase¶
typedef struct nodo Nodo;
struct nodo
{
int dato;
Nodo *sig;
};Por qué falla: Nodo no respeta ni el snake_case de identificadores
(0x0102h: Los argumentos de función y las variables locales deben usar snake_case en minúsculas) ni el sufijo _t. El lector no distingue a simple vista un
tipo de una función, y el estilo se desvía del resto del catálogo.
❌ Contraejemplo 2 — Uso directo de struct sin alias¶
struct nodo
{
int dato;
struct nodo *sig;
};
void agregar(struct nodo *cabeza, int valor);
struct nodo *buscar(struct nodo *cabeza, int valor);Por qué falla: la interfaz repite struct nodo en cada firma. Es fácil omitir la
palabra struct y obtener un error de tipo indefinido, y el código se vuelve
verboso justo donde la firma debería comunicar la intención.
✅ Ejemplo conforme 1 — Alias con sufijo _t¶
typedef struct nodo nodo_t;
typedef enum estado estado_t;
struct nodo
{
int dato;
nodo_t *sig;
};
enum estado
{
ESTADO_NUEVO,
ESTADO_LISTO,
ESTADO_ERROR
};La forma typedef struct nodo nodo_t; separa la etiqueta del nombre de tipo y
permite que el struct se complete después, técnica base de los punteros
opacos de 0x301Dh: Diseñá los Tipos de Datos Abstractos utilizando punteros opacos.
✅ Ejemplo conforme 2 — Tipo opaco con alias¶
/* lista.h */
typedef struct lista_t lista_t;
lista_t *lista_crear(void);
void lista_destruir(lista_t **lista);
/* lista.c */
struct lista_t
{
nodo_t *cabeza;
size_t cantidad;
};El alias lista_t aparece en la cabecera sin representación; el struct se
define en el .c. Así el cliente usa un único nombre corto y la implementación
queda libre de cambiar sus campos.
⚠️ Casos límite¶
Tipos internos: el sufijo
_ttambién aplica a lostypedefprivados del.c; la convención no depende de la visibilidad.structanónimo:typedef struct { int x; } punto_t;es válido, pero impide referenciar la etiqueta; usalo sólo si nunca la necesitás.
Cómo detectarla¶
| Herramienta | Comando | Señal |
|---|---|---|
gaff | gaff check archivo.c | typedef cuyo alias no termina en _t o no está en snake_case. |
gcc / clang | gcc -Wall -Wextra -std=c11 ... | No detecta la convención de nombres. |
| Revisión manual | — | Firmas con struct x repetido en lugar de un alias. |
Checklist de autocontrol¶
¿Definí un alias
typedefpara cadastruct/enum/union?¿El alias termina en
_t?¿El alias está en
snake_caseminúsculo?¿Usé el alias en todas las firmas en lugar de
struct x?¿Evité reutilizar nombres reservados por la biblioteca estándar?
Reglas relacionadas¶
0x301Dh: Diseñá los Tipos de Datos Abstractos utilizando punteros opacos — el alias del TAD opaco se declara sin representación.
0x0102h: Los argumentos de función y las variables locales deben usar snake_case en minúsculas — los identificadores deben usar
snake_caseen minúsculas.0x0108h: Prohibición de identificadores con caracteres no ASCII (acentos, ñ) — los identificadores deben restringirse a ASCII.