TL; DR Не заботьтесь о таких мелочах, если вы не знаете, что должны.И если вам нужно, вам нужно проанализировать конкретную сборку.
В общем, с чисто языковой точки зрения такие вопросы не имеют смысла.Для чего это стоит, компилятор c ++ может нанести вред производительности, если он этого пожелает.Любая программа, демонстрирующая такое же поведение, также легальна, и производительность не является видимым эффектом.
Разговор о производительности имеет смысл только в конкретном приложении, которое представляет собой конкретную сборку с использованием определенного компилятора и конфигурации, особенно оптимизации.
Полное изучение: Я буду использовать clag 7.0.0 на проводнике компилятора Godbolt
Ваш случай странный, поскольку он определяет глобальные значения. Для оптимизации по умолчаниюпараметры:
- c'tor был сгенерирован и объект сохранен как нули
- не было кода, и объект был сгенерирован как 3 единицы
Очевидно, что вариант 2 выглядит лучше:
__cxx_global_var_init: # @__cxx_global_var_init
push rbp
mov rbp, rsp
movabs rdi, offset bar
call foo::foo() [base object constructor]
pop rbp
ret
foo::foo() [base object constructor]: # @foo::foo() [base object constructor]
push rbp
mov rbp, rsp
mov qword ptr [rbp - 8], rdi
mov rdi, qword ptr [rbp - 8]
mov byte ptr [rdi], 1
mov byte ptr [rdi + 1], 1
mov byte ptr [rdi + 2], 1
pop rbp
ret
_GLOBAL__sub_I_example.cpp: # @_GLOBAL__sub_I_example.cpp
push rbp
mov rbp, rsp
call __cxx_global_var_init
pop rbp
ret
bar:
.zero 3
bar2:
.byte 1 # 0x1
.byte 1 # 0x1
.byte 1 # 0x1
Однако использование -O1
сокращает код без разницы:
bar:
.byte 1 # 0x1
.byte 1 # 0x1
.byte 1 # 0x1
bar2:
.byte 1 # 0x1
.byte 1 # 0x1
.byte 1 # 0x1
При использовании foo
в качестве типа в программе генерируется ctor дляоба случая -O0
и -O1
(один и тот же ctor для каждого случая, разные для уровня оптимизации).См .: https://godbolt.org/z/0il6ou
А для -O2
объекты растворяются.