Сырые указатели¶
В Ü существует тип сырых указателей, подобный (отчасти) таковому во многих низкоуровневых языках, таких, как Си. В Ü сырые указатели синтаксически и функционально несколько отличаются от Си, но главный смысл всё же остаётся.
Сырые указатели предназначены для использования в низкоуровневом коде, таком как код контейнеров, код взаимодействия с другими языками и т. д.
Для указателей не работает проверка ссылок, поэтому операция рызыменования указателя дозволена только в unsafe
блоках.
Объявляется тип сырого указателя через символ $
и пару круглых скобок, следующих за ним, в которых указывается тип элемента.
Примеры:
type i32_ptr = $(i32); // указатель на тип "i32".
type tup_ptr = $(tup[i32, f32]); // указатель на тип кортежа.
type bool_ptr_ptr = $($(bool)); // указатель на указатель на "bool".
Значение типа указателя можно получить из изменяемой ссылки с помощью оператора состоящего из лексемы $<
и пары круглых скобок с выражением внутри.
Получение ссылки из указателя выполняется с помощью обратного оператора, начинающегося с лексемы $>
.
var i32 mut x= 0;
var (i32) x_ptr = $<(x); // Преобразование ссылки на "x" в сырой указатель.
unsafe{ $>(x_ptr) = 24; } // Разыменование указателя и присвоение значения полученной ссылке. Дозволено только в "unsafe" коде.
Стоит отметить, что в Ü, в отличие от C++ нету модификаторов изменяемости у типов указателей. Все указатели считаются указывающими на изменяемые данные. Поэтому указатель можно получить только из изменяемой ссылки и оператор разыменования указателя возвращает изменяемую ссылку.
Указатель можно инициализировать zero_init
инициализатором, в таком случае указатель будет должным образом занулён.
Арифметика указателей¶
В Ü существует возможность осуществлять арифметические операциями с указателями. Возможны следующие операции:
Сложение указателя с целым числом. Разрешено сложение с целыми знаковыми и беззнаковыми числами, но с размером не большим размера указателя. Возможно сложение как указателя с числом, так и числа с указателем (операция сложения коммутативна). Существует оператор
+=
для указателя и числа. Результатом сложения указателя и числа является указатель, указывающий на адрес, больший оригинального на переданное число, помноженное на размер типа элемента указателя.Вычитание целого числа из указателя. Разрешено вычитание целего числа (знакового или беззнакового) из указателя. Размер целого числа должен быть не больше размера указателя. Существует оператор
-=
для указателя и числа. Результатом вычитания числа из указателя является указатель, указывающий на адрес, меньший оригинального на переданное число, помноженное на размер типа элемента указателя.Разность указателей. Разрешено вычислять разность указателей через оператор
-
. Тип элемента указателя при этом должен иметь ненулевой размер. Результатом разности указателей является целое знаковое число типаssize_type
, равное разнице значений указателей, делённой на размер типа элемента указателя.Инкремент и декремент. Для указателей возможно использование
++
и--
. Значение указателя будет увеличено или уменьшено на размер типа элемента.Сравнение указателей. Все операторы сравнения -
==
,!=
,<
,<=
,>
,>=
применимы к указателям.
Примеры:
var [ i32, 8 ] mut arr= zero_init;
var $(i32) ptr0= $<(a[0]);
auto ptr3 = ptr0 + 3; // ptr3 указывает на arr[3]
auto ptr4 = 4 + ptr0; // ptr4 указывает на arr[4]
auto diff5_2 = $<(a[5]) - $<(a[2]); // diff = 3
auto diff1_6 = $<(a[1]) - $<(a[6]); // diff = -5
auto mut ptr = $<(a[2]); // ptr указывает на arr[2]
++ptr; // ptr теперь указывает на arr[3]
ptr+= 3; // ptr теперь указывает на arr[6]
--ptr; // ptr теперь указывает на arr[5]
ptr-= 4; // ptr теперь указывает на arr[1]
auto is_3_less_4 = ptr3 < prt4; // true
auto is_3_greater_0 = ptr3 > prt0; // true
auto is_3_equal_4 = ptr3 == prt4; // false
auto is_4_less_or_equal_4 = ptr4 <= ptr4; // true