Si has seguido la filosofía detrás de Zig por algún tiempo, sabrás que Zig nació con la idea de corregir o mejorar aspectos que causan problemas a desarrolladores del lenguaje C. Similarmente, se podría decir que Rust es un paralelo, pero para quienes programan en C++.
En esta entrada veremos algunas áreas en las que Rust ofrece más garantías de seguridad comparado a Zig. Ojo, no significa que Rust sea superior por este hecho, simplemente ofrece diferentes concesiones en comparación. Como siempre, depende del caso de uso.
Si siguen mi blog, sabrán que mi preferencia es Zig. No lo puedo explicar, simplemente me gusta. Pero a continuación expondré algunas áreas en las cuales Rust ofrece mayores garantías:
Seguridad de Memoria
Ambos lenguajes carecen de un recolector de basura para la gestión de memoria. Sin embargo, esa gestión difiere entre ambos lenguajes.
Rust utiliza una funcionalidad llamada Borrow Checker, mientras que en Zig esta gestión es completamente manual y resposabilidad del programador. Dicho eso, Zig promueve ciertas practicas en la creacion y destrucción de asignadores de memoria lo cual en la práctica lo convierte en un lenguaje más seguro que C sin sacrificar desempeño.
Las garantías de seguridad impuestas por Rust mediante el Borrow Checker, generalmente ayudan a prevenir vulnerabilidades relacionadas con apuntadores colgantes, use-after-free (relacionado también a los apuntadores colgantes) y double free (ocurre cuando se intenta liberar un recurso en memoria que ya fue liberado previamente).
Seguridad en Hilos
El compilador de Rust impone la seguridad en hilos al momento de
compilación. Los Traits de Send
y Sync
se aseguran de que la data
sea compartida de manera segura entre hilos y previniendo condiciones de
carrera. En Zig, la misma implementación debe realizarse de forma manual.
Seguridad relacionada al valor null
El tipo Option
en Rust maneja a posibilad de None
, lo cual evita que
un apuntador vacío sea “desreferenciado”. Zig, por su parte, ofrece
mecanismos como los tipos opcionales, pero en teoria, a diferencia de Rust
creo (alguien corríjame si me equivoco) que si es posible desreferenciar
un apuntador en estado null
accidentalmente.
Invalidación de un Iterador
Modificar un iterable mientras se está iterando sobre el mismo puede resultar en comportamientos indefinido o resultados inesperados. El compilador de Rust previene al usuario de este tipo de problemas, mientras que Zig da mayor libertad al respecto.
Memoria no Inicializada
En Rust es necesario inicializar una variable antes de usarla. En Zig es posible usar una variable solo declarando su tipo, por lo cual hay que ser más cuidadoso.
Todo se resume al caso de uso. En ocasiones, el control adicional que brinda Zig al usuario es preferible sobre la seguridad adicional que ofrece Rust, especialmente cuando se está trabajando a un menor nivel o más cerca al hardware. En esos casos, queda entonces en manos del usuario la seguridad y se espera que este sepa lo que está haciendo.