Константные выражения¶
В Ü существуют выражения, называемые константными, чьё значение может быть вычислено на этапе сборки программы.
Такие выражения могут быть применены в ряде мест, где это требуется - в размерах типов массивов, в параметрах шаблонов, в конструкциях static_assert
и static_if
.
Выражение является константным, если:
переменные, входящие в его состав, константны
функции и операторы, входящие в состав константных выражений, удовлетворяют требованиям константности (
constexpr
)
«constexpr» типы¶
Переменные, входящие в константные выражения, должны быть константными. Константными могут быть только переменные, имеющие constexpr
тип.
constexpr
типами являются:
все фундаментальные типы
все перечисления
все указатели на функции
массивы с типами элементов, являющимися
constexpr
кортежи с типами элементов, являющимися
constexpr
некоторые типы структур
Требования к constexpr
структурам:
типы всех полей должны быть
constexpr
они не должны иметь изменяемых (
mut
) ссылочных полейони не должны иметь явно обозначенных конструкторов копирования, копирующих операторов присваивания, деструкторов
«constexpr» функции¶
Функции, которые могут быть использованы в константных выражениях, должны быть явно помечены с использованием ключевого слова constexpr
.
Такие функции должны иметь тело тут-же, не допускается объявление constexpr
для прототипа функции.
Требования к constexpr
функциям:
типы их аргументов и возвращаемых значений должны быть
constexpr
, но не указателями на функциюони не могут быть помечены как
unsafe
они не могут содержать
unsafe
блоковони не должны связывать ссылки (см. связывание ссылок)
они не могут содержать объявлений переменных не
constexpr
типовони не могут содержать вызовов не
constexpr
функцийони не могут содержать вызовов функций по указателю
constexpr
функции могут иметь изменяемые ссылочные аргументы, но такие функции нельзя позвать для constexpr
аргументов.
В constexpr
функциях дозволены все остальные конструкции, кроме запрещённых, в т. ч. циклы, условия, halt
и т. д.
Пример constexpr
функции:
fn constexpr ArrSumm( [ u32, 16 ]& arr ) : u32
{
auto mut res= 0u;
auto mut i= 0s;
while( i < 16s )
{
res+= arr[i];
++i;
}
return res;
}
«constexpr» переменные¶
Неизменяемые переменные с constexpr
типом и константно-инициализированные являются константными.
Если необходимо удостовериться в константности переменной, её следует объявить с модофикатором изменяемости constexpr
.
auto x= 0; // Переменная неявно объявлена как неизменяемая, инициализатор является константным, как следствие, переменная будет константной
auto imut y= x + 5; // Аналогично, но на сей раз переменная объявлено неизменяемой явно
var i32 z(66), imut v(-5), w= y / 2; // все эти переменные будут константными
var [ i32, 2 ] arr[ 0 + z, w * 10 ]; // и эти тоже
auto constexpr x_copy= x; // явно требуем константности
var i32 constexpr ensure_constant(y); // явно требуем константности
var i32 mut nonconst= 0; // хоть инициализатор и константный, переменная константной не будет
auto constexpr wtf= nonconst; // будет порождена ошибка - инициализатор переменной неконстантен