Стоит ли объявлять constexpr-переменные static?
Существуют ли ситуации, когда локальные constexpr переменные имеет смысл объявить без ключевого слова static?
Т.е. есть ли смысл объявлять так:
void foo() {
constexpr auto x = 42;
а не так:
void foo() {
static constexpr auto x = 42;
Пример, когда со static gcc генерит лучше код.
Если использовать какой-нибудь ресурсоёмкий инициализатор типа std::array<double, 10000>{}, то разница ещё более заметна. Вариант без static будет вызывать memset на 80000 байт каждый вызов функции, в то время как со static - ссылаться на одну запись из .zero памяти. Пример.
Ответы (2 шт):
Например, если вы берете адрес переменной (или ссылку) и переедаете ее за пределы функции, поведение отличается принципиально. Хотя это странный способ использования constexpr, но разрешенный стандартом.
Если адрес переменной x никак не используется, то в режиме оптимизации, компиляторы сгенерирую один и тоже код, в котором память под x не будет выделена ни на стеке, ни в сегменте констант.
Понятие лучше - понятие относительное. Если вы объявляете переменную со static, то получается переменная с глобальным временем жизни и локальной областью видимости. А без static - переменная с локальными временем жизни и областью видимости.
А constexpr - не панацея, потому что компилятор считает, что всегда в коде может встретиться const_cast<>. Опять-таки, в c/c++ - константность скорее возможность компилятора помочь программисту избежать ошибок.
Здесь скорее нужно выбирать, в какой переменной вы нуждаетесь, исходя из логики вашей программы.