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