Stati c переменные инициализируются только один раз.
Второй (и последующий) момент инициализации пропускается.
Здесь также у вас есть 2 разные функции test
. 1 для каждого уникального типа параметра шаблона.
Пример простого вызова функции из вашего кода:
auto f() { return test<Position>(1); }
Это приведет к следующему коду ассемблера, где вы можете видеть, что это проверка, чтобы проверить, была ли переменная уже инициализирована или вернуть уже установленное значение. Если он не был установлен, то он будет настроен как потокобезопасный.
f():
movzx eax, BYTE PTR guard variable for int test<Position>(int)::y[rip]
test al, al // <----- check if intialized
je .L13 // <----- if not initialized go to .L13
// otherwise return the value
mov eax, DWORD PTR int test<Position>(int)::y[rip]
ret
.L13:
sub rsp, 8
mov edi, OFFSET FLAT:guard variable for int test<Position>(int)::y
call __cxa_guard_acquire
test eax, eax
jne .L14
mov eax, DWORD PTR int test<Position>(int)::y[rip]
add rsp, 8
ret
.L14:
mov DWORD PTR int test<Position>(int)::y[rip], 1
mov edi, OFFSET FLAT:guard variable for int test<Position>(int)::y
call __cxa_guard_release
mov eax, DWORD PTR int test<Position>(int)::y[rip]
add rsp, 8
ret