CAPÍTULO 5

Memoria y Cadenas


Aquí viene una parte especialmente interesante: cómo usa Zig la memoria. Creo que antes, en alguna parte de este libro, te mencioné que el sistema operativo, cuando lanza un programa, le dedica una parte de la memoria disponible. Esto es necesario para todos los programas que ejecutamos en el ordenador, en un smartphone, o un dispositivo totalmente diferente como una nevera, un robot o una cámara de fotos.

Los programas siempre necesitan memoria para poder funcionar, y no solo para almacenar datos, también la necesitan para ejecutar sus propias instrucciones.

Zig, al igual que cualquier lenguaje compilado, convierte al final las instrucciones que hemos escrito en código máquina nativo. Ese código es mucho más compacto y difícil de leer que lo que hemos escrito en nuestros ficheros.

Se puede decir que Zig es un lenguaje de bajo nivel por lo cerca que está de ese lenguaje de la máquina, aunque en realidad el código fuente que escribimos es bastante abstracto y estilizado en comparación con el resultado de la compilación.

En cualquier caso, ahora mismo no nos preocupa demasiado indagar en la parte de las instrucciones compiladas (ya lo miraremos más en detalle en un futuro volúmen de Zen of Zig), pero cuando compilamos un programa hay una parte de los datos que en Zig se definen en lo que llamamos “tiempo de compilación”.

Estos datos van embutidos en el propio programa compilado - listos para ser cargados en la memoria asignada al programa por el sistema operativo. Conocerlos en ese tiempo de compilación garantiza que se conoce su tipo y tamaño, algo que es muy importante para la ejecución correcta del programa.

Ahora, igual me dices: pero “hay lenguajes que no tienes que definir tanto tipo y tanto tamaño de datos y no pasa nada.” . Eso es cierto. Hay muchísimos lenguajes que no tienen nada que ver con Zig, ni con lenguajes de bajo nivel. Hasta algunos lenguajes considerados de “bajo nivel” no requieren de tantas definiciones. Lo que ocurre es que Zig, en concreto, está muy próximo al lenguaje de la máquina, y por eso necesita definir y establecer muchas cosas para asegurarse de que todo funcione correctamente, en la medida de lo posible.

Por ponerte un ejemplo: es un lenguaje tan bien hecho que se puede desarrollar un servidor web que sirva páginas a la velocidad del rayo… pero también es tan bajo nivel que podrás escribir controladores (drivers) para un dispositivo.

¿Te acuerdas cómo cuando hablamos sobre Variables y constantes intentamos hacer esto?

vars.zig

const std = @import("std");

pub fn main() void {

    var n_a = 1;

    n_a = 2;

}

El compilador nos decía comptime_int - algo así como un número entero de tiempo de compilación tiene que ser o una constante o estar marcada como comptime, y además nos añade una nota:

“Para modificar esta variable durante el tiempo de ejecución, tiene que ser definida con un tipo explícito de tamaño fijo.”

 Es decir, hay que definir si su tipo es u8, u16, o cualquier otro que necesitemos:

$ zig run vars.zig

vars.zig:4:9: error: variable of type 'comptime_int' must be const or comptime

    var n_a = 1;

        ^~~

vars:5:7: note: to modify this variable at runtime, it must be given an explicit fixed-size number type

Como ya sabes, Zig a veces es capaz de adivinar (inferir) el tipo de una variable o constante que vamos a usar. A veces. Por ejemplo, con literales numéricos (números escritos directamente en el código) como 1, Zig los infiere como comptime_int, aunque incluso en esos casos puede pedirnos que definamos explícitamente el tamaño de la variable, como ocurre aquí.

Resumen del capítulo
Dónde están los bytes
© 2025 Zen of Zig