TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #781 5.32K
​​WAT
#новичкам

Спасибо, @Ivaneo, за любезно предоставленный примерчик в рамках рубрики #ЧЗХ.

Дан простой кусочек кода:
const char* s1 = "First";
constexpr char* s2 = "Second";
constexpr const char* s3 = "Third";

static_assert(std::is_const_v<decltype(s1)>);
static_assert(std::is_const_v<decltype(s2)>);
static_assert(std::is_const_v<decltype(s3)>);


Все просто. Тип 3-х переменных проверяется на константность.

Вопрос: сможете сказать без компилятора какой из трех вариантов нормально соберется, какой выдаст assert, а какой выдаст warning?

Возьмите паузу на подумать.

Ответ будет такой:

static_assert(std::is_const_v<decltype(s1)>); // выдаст ассерт
static_assert(std::is_const_v<decltype(s2)>); // выдаст варнинг
static_assert(std::is_const_v<decltype(s3)>); // нормально скомилится


ЧЗХ? Там же все константное?

Здесь дело в особенностях константности указателей. Чуть подробнее мы это разбирали в этом посте, но сейчас краткая выжимка.

Бывают константные указатели и указатели на константы. И это разные типы! Первый нельзя передвигать, но можно изменять данные, на которые он указывает. Второй можно передвигать, но данные изменить не получится.

Так вот ассерты проверяют является ли сам указатель константным. s1 - это неконстантный указатель на константу, поэтому срабатывает ассерт.

Теперь с constexpr разбираемся. Этот спецификатор подразумевает const. И так как его нельзя применять более одного раза при объявлении переменной, то он применяется к самой "верхушке" типа. То есть s2 и s3 становятся константными указателями. И для них ассерты не срабатывают.

Для s2 выдается варнинг, потому что мы пытаемся присвоить строковый литерал, который имеет тип const char[], то есть массив константных символов, к указателю на неконстанту. В нормальной ситуации это бы вызвало ошибку компиляции, но такие преобразования возможны в С. И С++ сохраняет здесь совместимость, хоть и стремается этого и генерирует предупреждение о такой опасной ситуации.

Все примеры довольно просто объяснимы, хотя на первый взгляд лицо деформируется в вопросительный знак. Помните об особенностях константности указателей и будет вам счастье.

Be amazed. Stay cool.

#cppcore
  • ❤ 30
  • 👍 19
  • 🤯 11
  • 🔥 3
  • ❤‍🔥 2
  • 😁 2
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →