מצביע
מודל 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; // שגיאה
// var b: bool = null; // שגיאה
אריתמטיקת מצביעים
Wave תומכת באריתמטיקת מצביעים הבאה.
ptr + int: Pointer Forwarding מבוסס GEPint + ptr: פעולה זההptr - int: Pointer Backwarding מ בוסס 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 (הפרש בתים)
השוואת מצביעים
ניתן להשתמש במצביעים עבור השוואה.
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 הפניה הפוכה. מומלץ להכניס דפוס בדיקה null מפורש לפני deref.