Saltar al contenido

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

C
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 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.

C
#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>:

C
#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 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:

C
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

C
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

C
constexpr int TAM = 256;     // evaluado en compilación, con tipoint 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

C
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

C
int a = 5;typeof(a) b = 10;         // b es inttypeof_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

C
_BitInt(4)  nibble = 7;        // exactamente 4 bits, con signounsigned _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.