wandres.dev
PRACTICANTE · Tipos y novedades de C23

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.

⏱ 16 min

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.

🎯 Al terminar esta lección sabrás
  • 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ón
double preciso  = 3.14159; // doble precisión (el habitual para decimales)
bool   activo   = true;    // en C23, bool/true/false son palabras clave
⚠️
Los 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 signo
int32_t  con32   = -1000;      // exactamente 32 bits, con signo
uint64_t grande  = 1ULL << 40; // exactamente 64 bits
💡
En 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 mundo

El 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, inferido
auto 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 tipo
int buffer[TAM];             // válido como tamaño de array

Mejor 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 seguro

nullptr 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 int
typeof_unqual(a) c = 3;   // como typeof pero quita const/volatile

Base 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 signo
unsigned _BitInt(24) color;    // 24 bits justos, para RGB por ejemplo

Control 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
  1. Imprime sizeof de int, long, void* y long double en tu máquina.
  2. Reproduce la trampa del signo con unsigned vs int y observa el aviso de -Wextra.
  3. Declara constantes con constexpr y úsalas como tamaño de un array.
  4. Usa auto y typeof en un par de declaraciones.
  5. Define un _BitInt(N) y comprueba su rango con un desbordamiento a propósito.