پوینتر
مدل نوع حافظه صریح Wave
طراحی پوینتر در Wave بر اساس مدل نوع حافظه صریح Wave است. این مدل هدفش تعریف اشارهگرها و آرایهها بهعنوان نوع حافظه صریح در سطح زبان است، نه ترفندهای دستوری یا انتزاعهای کتابخانهای.
با این طراحی، در Wave، اشارهگر بهعنوان نوع ptr<T> بیان میشود تا روشن کند که این نوع، آدرسی از حافظه است که مقداری از نوع خاص T را نگه میدارد.
این رویکرد اجازه میدهد که اشارهگر بخشهایی از سیستم تایپ باشد، نه عملگر یا دستور زبانی، تا ساختار حافظه را بهصورت شهودیتر و یکپارچهتر نمایش دهد.
در Wave، اشارهگرها دارای تایپ صریح به شکل ptr<T> هستند.
برای بهدست آوردن آدرس از & و برای ارجاعدهی مجدد از deref استفاده میشود.
اعلان و مقداردهی اولیه
var x: i32 = 10;
var p: ptr<i32> = &x;
نوع اشارهگرها میتواند تودرتو باشد.
var p1: ptr<i32> = &x;
var p2: ptr<ptr<i32>> = &p1;
ارجاعدهی مجدد
var x: i32 = 10;
var p: ptr<i32> = &x;
println("{}", deref p); // 10
deref p = 20;
println("{}", x); // 20
قواعد لیترال null
null یک لیترال رسمی میباشد. این یک شناسه نیست و نمیتواند به عنوان نام متغیر استفاده شود.
قواعد اصلی:
nullتنها میتواند به مقصدptr<T>اختصاص یابد.- به نوعهای غیراشارهگری مانند
i32،bool،array<...>نمیتوان تخصیص داد. - نمیتوانید اشارهگر را با لیترالهای عدد صحیحی مانند (
0,123,-1و غیره) مقداردهی اولیه کنید. بهطور صریح ازnullاستفاده کنید.
var p: ptr<i32> = null;
var arrp: ptr<array<i32, 3>> = null;
// var n: i32 = null; // ERROR
// var b: bool = null; // ERROR
حساب اشارهگر
Wave از محاسبات اشارهگری زیر پشتیبانی میکند.
ptr + int: پیشروی اشارهگر مبتنی بر GEPptr + int: عملیات مشابهint + ptr: عقبروی اشارهگر مبتنی بر GEPptr - ptr: محاسبه تفاوت بایت درi64
نکته:
ptr<T> +/- nبراساس اندازهT(sizeof(T)) حرکت میکند.- بهعبارت دیگر،
ptr<i32> + 3بهاندازه+12بایت حرکت میکند.
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 (byte diff)
مقایسه اشارهگر
اشارهگرها را میتوان برای مقایسه استفاده کرد.
if (p == null) { ... }
if (p != null) { ... }
if (p1 == p2) { ... }
ارتباط با آرایهها
آرایه اشارهگر:
var a: i32 = 10;
var b: i32 = 20;
var arr: array<ptr<i32>, 2> = [&a, &b];
println("{} {}", deref arr[0], deref arr[1]);
اشارهگر آرایه:
var p: ptr<array<i32, 3>> = &[1, 2, 3];
if (p != null) {
println("{}", deref p[1]);
}
نکات ایمنی
در حال حاضر، Wave دارای مدل ایمنی برای اشارهگرها مبتنی بر مالکیت/طول عمر مانند Rust نیست.
بنابراین، ارجاعدهی مجدد null بهطور خودکار مسدود نمیشود. الگوی اضافه کردن چککردن deref بهصورت صریح قبل از null توصیه میشود.
