Tipos fundamentales y novedades de C23
Los tipos de C, sus tamaños y trampas de signo, los enteros de ancho fijo, y las novedades de C23 que modernizan el lenguaje: auto, constexpr, nullptr, typeof y _BitInt.
En C, los tipos no son una formalidad: definen cuántos bytes ocupa un dato, cómo se interpreta y qué operaciones son seguras. Dominar el sistema de tipos —incluidas sus trampas históricas y las mejoras de C23— es la base de todo código correcto.
- Los tipos fundamentales y sus tamaños.
- Enteros de ancho fijo con
<stdint.h>. - Las trampas de signo y las promociones.
- Las novedades de C23:
auto,constexpr,nullptr,typeof,_BitInt.
Los tipos fundamentales
int entero = 42; // entero, al menos 16 bits (normalmente 32)char letra = 'A'; // 1 byte; ¿con signo o sin? depende (¡trampa!)float decimal = 3.14f; // coma flotante simple precisióndouble preciso = 3.14159; // doble precisión (el habitual para decimales)bool activo = true; // en C23, bool/true/false son palabras claveLos tamaños de C no son fijos (por defecto)
Sorpresa clásica: el estándar C solo garantiza tamaños mínimos y relaciones (int ≥ 16 bits, long ≥ 32, sizeof(char) == 1). El tamaño real depende de la plataforma. Un int suele ser 32 bits hoy, pero confiar en ello es un bug esperando a ocurrir. Comprueba siempre con sizeof, e imprime con el especificador correcto.
#include <stdio.h>printf("int: %zu bytes, long: %zu, void*: %zu\n", sizeof(int), sizeof(long), sizeof(void *));Enteros de ancho fijo
Cuando el tamaño debe ser exacto (protocolos, formatos binarios, hardware), usa <stdint.h>:
#include <stdint.h>uint8_t byte = 255; // exactamente 8 bits, sin signoint32_t con32 = -1000; // exactamente 32 bits, con signouint64_t grande = 1ULL << 40; // exactamente 64 bitsEn sistemas, prefiere anchos fijos
Para lógica de negocio, int está bien. Pero en programación de sistemas —donde manejas bytes, registros de hardware o formatos de red— usa uint8_t, int32_t, etc. Dejan la intención explícita y el tamaño garantizado en cualquier plataforma. Es la diferencia entre código que funciona “en mi máquina” y código portable de verdad.
La trampa del signo
Mezclar enteros con y sin signo es una fuente inagotable de bugs, porque C hace conversiones implícitas que no esperas:
unsigned int u = 1;int s = -1;if (s < u) printf("menor\n"); // ¡NO se imprime!// -1 se convierte a un unsigned enorme; -1 > 1 en ese mundoEl compilador te avisa de esto con -Wextra (-Wsign-compare). Es otra razón para compilar siempre con avisos (nivel 2). Las promociones enteras las verás a fondo en el nivel 5.
Novedades de C23
C23 moderniza el sistema de tipos sin traicionar la filosofía de C:
auto — inferencia de tipos
auto x = 42; // int, inferidoauto y = 3.14; // double, inferidoÚtil para no repetir tipos largos. No abuses: en C, tipos explícitos suelen comunicar mejor.
constexpr — constantes de compilación
constexpr int TAM = 256; // evaluado en compilación, con tipoint buffer[TAM]; // válido como tamaño de arrayMejor que #define TAM 256 (que es texto sin tipo) y que un const int (que no siempre es una constante de compilación en C).
nullptr — el puntero nulo con tipo
int *p = nullptr; // en vez de NULL; tiene tipo nullptr_t, más seguronullptr evita las ambigüedades históricas de NULL (que a veces es 0, a veces (void*)0).
typeof — el tipo de una expresión
int a = 5;typeof(a) b = 10; // b es inttypeof_unqual(a) c = 3; // como typeof pero quita const/volatileBase para macros genéricas seguras (lo verás con _Generic, nivel 15).
_BitInt(N) — enteros de anchura exacta en bits
_BitInt(4) nibble = 7; // exactamente 4 bits, con signounsigned _BitInt(24) color; // 24 bits justos, para RGB por ejemploControl de anchura al bit, útil en hardware, compresión y aritmética precisa.
C23 quita asperezas, no añade capas
Fíjate en el patrón de todas estas novedades: cada una reemplaza un truco peligroso por algo seguro y con tipo. constexpr sustituye macros de constantes; nullptr sustituye el ambiguo NULL; typeof habilita macros genéricas sin hacks; _BitInt da precisión que antes requería manipulación manual de bits. C23 no te aleja del metal —sigues controlando cada byte— sino que te da herramientas más afiladas para hacerlo con menos riesgo. Adóptalas: es el C de siempre, mejor.
Explora los tipos
- Imprime
sizeofdeint,long,void*ylong doubleen tu máquina. - Reproduce la trampa del signo con
unsignedvsinty observa el aviso de-Wextra. - Declara constantes con
constexpry úsalas como tamaño de un array. - Usa
autoytypeofen un par de declaraciones. - Define un
_BitInt(N)y comprueba su rango con un desbordamiento a propósito.