Puntero
Modelo de Tipo de Memoria Explícita de Wave
El diseño de puntero de Wave se basa en el Modelo de Tipo de Memoria Explícita de Wave. Este modelo pretende definir los punteros y arreglos como tipos de memoria explícitos a nivel del lenguaje, en lugar de trucos gramaticales o abstracciones de la biblioteca.
Con este diseño, en Wave los punteros se expresan en la forma de tipo ptr<T>, mostrando claramente que es un tipo que apunta a la dirección de memoria que almacena un valor del tipo T.
Este enfoque permite expresar las estructuras de memoria de manera más intuitiva y coherente al tratar los punteros como parte del sistema de tipos, en lugar de operadores o sintaxis de declaración.
En Wave, un puntero es un tipo explícito en la forma ptr<T>.
Para obtener una dirección se utiliza &, y para la desreferencia deref.
Declaración e inicialización
var x: i32 = 10;
var p: ptr<i32> = &x;
El tipo puntero se puede anidar.
var p1: ptr<i32> = &x;
var p2: ptr<ptr<i32>> = &p1;
Desreferencia
var x: i32 = 10;
var p: ptr<i32> = &x;
println("{}", deref p); // 10
deref p = 20;
println("{}", x); // 20
Regla del literal null
null es un literal formal. No es un identificador y no se puede usar como nombre de variable.
Regla clave:
nullsolo se puede asignar a un destinoptr<T>.- No se puede asignar a tipos no punteros como
i32,bool,array<...>. - No se pueden inicializar punteros con literales enteros (
0,123,-1, etc.). Utiliza explícitamentenull.
var p: ptr<i32> = null;
var arrp: ptr<array<i32, 3>> = null;
// var n: i32 = null; // ERROR
// var b: bool = null; // ERROR
Aritmética de punteros
Wave soporta la siguiente aritmética de punteros.
ptr + int: avance de puntero basado en GEPint + ptr: operación equivalenteptr - int: retroceso de puntero basado en GEPptr - ptr: cálculo de diferencia en bytesi64
Puntos:
ptr<T> +/- nse desplaza en función del tamaño deT(sizeof(T)).- Por ejemplo,
ptr<i32> + 3se desplaza+12en bytes.
var base: ptr<i32> = 0x1000 as ptr<i32>;
var p1: ptr<i32> = base + 3; // 0x1000 + 12
var p2: ptr<i32> = 2 + base; // 0x1000 + 8
var p3: ptr<i32> = base - 1; // 0x1000 - 4
var diff: i64 = p1 - base; // 12 (diferencia en bytes)
Comparación de punteros
Los punteros se pueden usar para comparaciones.
if (p == null) { ... }
if (p != null) { ... }
if (p1 == p2) { ... }
Relación con el arreglo
Arreglo de punteros:
var a: i32 = 10;
var b: i32 = 20;
var arr: array<ptr<i32>, 2> = [&a, &b];
println("{} {}", deref arr[0], deref arr[1]);
Puntero de array:
var p: ptr<array<i32, 3>> = &[1, 2, 3];
if (p != null) {
println("{}", deref p[1]);
}
Nota de seguridad
Wave no es actualmente un modelo de seguridad de puntero basado en propiedad/vida como Rust.
Por lo tanto, no impide automáticamente la desreferencia null. Se recomienda implementar un patrón de verificación null explícito antes de deref.