Является ли constexpr более "постоянным", чем const?

Язык программирования С++ Четвертое издание - Bjarne Stroustrup: (выделено мной)

2.2.3. Константы

В нескольких местах постоянные выражения требуются по языковым правилам (например, границы массива (§2.2.5, §7.3), метки случаев (п. 2.2.4, п. 9.4.2), некоторые аргументы шаблона (§25.2) и константы, объявленные с использованием constexpr). В других случаях оценка времени компиляции важна для производительности. Независимо от проблем с производительностью, понятие неизменности (объекта с неизменным состоянием) является важным аспектом дизайна (§10.4).

Кажется, что Stroustrup предлагает здесь, что constexpr обеспечивает неизменность объекта лучше, чем традиционная декларация const. Это верно? Существуют ли способы, в которых constexpr может быть более безопасным/менее волатильным, чем const, или Stroustrup просто означает, что, поскольку существуют способы использования constexpr, которые не поддерживаются с помощью const (см. Действительно ли необходим constexpr?), в таких случаях неизменяемость может быть обеспечена с помощью constexpr?

Ответы

Ответ 1

Он указывает в начале раздела:

С++ поддерживает два понятия неизменности

и он перечисляет const и constexpr, я не верю, что он пытается сказать, что constexpr гарантирует неизменность лучше, чем const, у них просто разные функции, хотя я признаю тот факт, что предложение цитирует раздел 10.4 Constant Expressions, похоже, подразумевают, что эта интерпретация не согласуется с остальной частью текста.

Переменная, которая const неизменна в этой области видимости, но может не быть const в большей области (например, опорный параметр const для функции), и это, возможно, тонкое различие, которое он пытается сделать, он говорит, что const:

используется в основном для указания интерфейсов

тогда как constexpr:

Это используется прежде всего для указания констант, позволяющих размещать данные в постоянной памяти

Любая переменная, которая является constexpr, должна оцениваться во время компиляции и, следовательно, использоваться там, где требуются постоянные выражения, тогда как переменная, которая передается как const в функцию, не должна быть const вне этой области.

Конечно, вы можете отбросить константу с помощью const_cast, но попытка изменить объект const - это поведение undefined и поэтому не менее неизменна, чем constexpr в этом смысле, из черновик С++ 11 раздел 7.1.6.1 cv-qualifiers:

любая попытка изменить объект const во время его жизни (3.8) приводит к поведению undefined

Джонатан Вакели отмечает, что переменная constexpr, такая как константные переменные, может иметь изменяемый элемент, но этот член не может использоваться в постоянном выражении.

Обратите внимание, что переменная constexpr также является константой из стандартного раздела проекта С++ 11 7.1.5 Спецификатор constexpr:

Спецификатор constexpr, используемый в объявлении объекта, объявляет объект как const.

Ответ 2

const не обеспечивает поразрядную константу, например. поскольку классы могут иметь изменяемые члены (типичным примером может быть частный мьютекс для внутренней синхронизации), и вы можете const_cast удалить константу из указателя.

constexpr объявляет постоянную переменную или функцию, которые могут быть вычислены во время компиляции, что подразумевает некоторые ограничения на то, что может быть объектом, но, я считаю, само ключевое слово не предоставляет никаких дополнительных гарантий во время выполнения по сравнению с const. См. Также это обсуждение.