TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #266 4.23K
​Константная инициализация. Ч1

Это первый шаг, который пытается выполнить компилятор, когда пробует инициализировать переменную. Для него требуется, чтобы инициализатор был константным выражением. То есть его можно было бы вычислить во время компиляции. И не путать с обычным const! Позже покажу почему.

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

constexpr double constexpr_var{1.0};
double const_intialized_var1{constexpr_var};
const double const_var{const_intialized_var1};
double const_intialized_var2{3.0};

С переменной constexpr_var все хорошо, константа присваивается константному выражению и инициализируется эта переменная первой. Далее устанавливается значение для const_intialized_var1. Несмотря на то, что эта переменная не константа, ее инициализатор - константное выражение, а этого достаточно для выполнения константной инициализации. Интересно, что дальше устанавливается значение переменной const_intialized_var2, а не const_var. Хоть const_var и константа, ее инициализатор не является константным выражением! Все потому, что у переменной const_intialized_var1 нет пометки const(constexpr), а значит, хоть она и проинициализирована константой, сама таковой не является. И const_var будет инициализироваться последней уже в рантайме.

Точнее немного не так. Она будет проиниализирована последней, но аж 2 раза! Первый раз - zero-инициализацией на этапе компиляции, второй раз - динамической в рантайме.

Чтобы не пустословить по чем зря, покажу вырезки из ассембера, которые подкрепляют мои слова. Вот чего нашел:
  .section  __DATA,__data
.globl _const_intialized_var1 ## @const_intialized_var1
.p2align 3, 0x0
_const_intialized_var1:
.quad 0x3ff0000000000000 ## double 1

.globl _const_intialized_var2 ## @const_intialized_var2
.p2align 3, 0x0
_const_intialized_var2:
.quad 0x4008000000000000 ## double 3

.section __TEXT,__const
.p2align 3, 0x0 ## @_ZL13constexpr_var
__ZL13constexpr_var:
.quad 0x3ff0000000000000 ## double 1

.zerofill __DATA,__bss,__ZL9const_var,8,3 ## @_ZL9const_var
.section __DATA,__mod_init_func,mod_init_funcs
.p2align 3, 0x0
.quad __GLOBAL__sub_I_main.cpp


constexpr_var инициализируется в текстовой секции. Не смотрите, что эта секция расположена в середине, стандарт гарантирует, что ее инициализация произойдет первой(в ином случае const_intialized_var1 досталась бы фига).

Дальше мы переходим к data секции, в которой подряд инициализируются const_intialized_var1 и _const_intialized_var2. И после всего этого в секции .zerofill у нас заполняется нулями const_var.

И в последнюю очередь, уже в рантайме, динамически ини
циализируется const_var.


.section __TEXT,__StaticInit,regular,pure_instructions
.p2align 4, 0x90 ## -- Begin function __cxx_global_var_init
___cxx_global_var_init: ## @__cxx_global_var_init
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movsd _const_intialized_var1(%rip), %xmm0 ## xmm0 = mem[0],zero
movsd %xmm0, __ZL9const_var(%rip)
popq %rbp
retq
.cfi_endproc


Это рантаймовая рутина, которая запускается перед вызовом main() и инициализирует const_var.

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

Define order of your life. Stay cool.

#cppcore #compiler
  • 👍 16
  • ❤ 7
  • 🤯 5
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 →