Сырые указатели¶
В Ü существует тип сырых указателей, подобный (отчасти) таковому во многих низкоуровневых языках, таких, как Си. В Ü сырые указатели синтаксически и функционально несколько отличаются от Си, но главный смысл всё же остаётся.
Сырые указатели предназначены для использования в низкоуровневом коде, таком как код контейнеров, код взаимодействия с другими языками и т. д.
Для указателей не работает проверка ссылок, поэтому операция рызыменования указателя дозволена только в 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