Почему constinit разрешает UB?
Скажем, я инициализирую переменные следующим образом:
#include <cstdint>
constexpr uint16_t a = 65535;
constinit int64_t b = a * a; // warning: integer overflow in expression of type 'int' results in '-131071' [-Woverflow]
constexpr int64_t c = a * a; // error: overflow in constant expression [-fpermissive]
Обаb
иc
производить неопределенное поведение из-за целочисленного переполнения.
Сconstinit
переменная инициализируется константой. Что не дает никаких гарантий относительно UB.
Сconstexpr
переменная инициализируется константным выражением. Постоянное выражение гарантирует отсутствие UB. Так что здесь целочисленное переполнение со знаком в ошибке. Но переменная также автоматически становится константой.
Итак, как мне лучше всего инициализировать неконстантную переменную с константным выражением?
Должен ли я писать
constexpr int64_t t = a * a; // error: overflow in constant expression [-fpermissive]
constinit int64_t b = t;
или
constinit int64_t b = []()consteval{ return a * a; }(); // error: overflow in constant expression
каждый раз?