Как известно, компилятор не может за-inline-ить функцию в некоторых случаях.
В частности, MSVC выдает warning C4714 в случае, если функция возвращает объект класса с деструктором, и выполняется сборка с /EHa,/EHs.
// EHastruct A
{
A() { }
~A() { MessageBox(0, "Hello, World!", 0, 0); }
};
__forceinline A GetA()
{ return A(); } // warning C4714int main(int/*argc*/, char* /*argv*/[])
{
{
auto a = GetA();
}
return 0;
}
Компилятор вставит в main вызов функции для "построения объекта a", которая ничего, кроме инициализации и деинициализации кода для раскрутки пустого стека, не делает.
Из-за этого, всякие конструкции типа ScopeGuard и SCOPE_EXIT Александреску не инлайнятся.
Мне кажется странным, что для построения guard-объекта вызывается функция, часто пустая, которая сама может бросить исключение.
Т.е., указывая компилятору некую функциональность, которую надо вызвать на выходе из scope, мы получаем в нагрузку определенный и не маленький оверхед.
Здравствуйте, rus blood, Вы писали:
RB>Т.е., указывая компилятору некую функциональность, которую надо вызвать на выходе из scope, мы получаем в нагрузку определенный и не маленький оверхед.
MSVC2010SP1 Release:
/EHsc (default):
; COMDAT main
_TEXT SEGMENT
__formal$ = 48
__formal$ = 56
main PROC ; COMDAT
; Line 13
$LN6:
sub rsp, 40 ; 00000028H
; Line 16
lea rdx, OFFSET FLAT:??_C@_0O@KLMCIIGF@Hello?0?5World?$CB?$AA@
xor r9d, r9d
xor r8d, r8d
xor ecx, ecx
call QWORD PTR __imp_MessageBoxA
; Line 18
xor eax, eax
; Line 19
add rsp, 40 ; 00000028H
ret 0
main ENDP
_TEXT ENDS
END
/EHs:
; COMDAT main
_TEXT SEGMENT
__formal$ = 48
__formal$ = 56
main PROC ; COMDAT
; Line 13
$LN6:
sub rsp, 40 ; 00000028H
; Line 16
lea rdx, OFFSET FLAT:??_C@_0O@KLMCIIGF@Hello?0?5World?$CB?$AA@
xor r9d, r9d
xor r8d, r8d
xor ecx, ecx
call QWORD PTR __imp_MessageBoxA
; Line 18
xor eax, eax
; Line 19
add rsp, 40 ; 00000028H
ret 0
main ENDP
_TEXT ENDS
END
/EHa:
; COMDAT text$x
text$x SEGMENT
$T66300 = 0
$T66307 = 8
__$ReturnUdt$ = 32
?dtor$0@?0??GetA@@YA?AUA@@XZ@4HA PROC ; `GetA'::`1'::dtor$0
push rbp
sub rsp, 32 ; 00000020H
mov rbp, rdx
mov eax, DWORD PTR $T66300[rbp]
and eax, 1
test eax, eax
je SHORT $LN4@dtor$0
and DWORD PTR $T66300[rbp], -2
mov rcx, QWORD PTR __$ReturnUdt$[rbp]
call ??1A@@QEAA@XZ ; A::~A
$LN4@dtor$0:
add rsp, 32 ; 00000020H
pop rbp
ret 0
?dtor$0@?0??GetA@@YA?AUA@@XZ@4HA ENDP ; `GetA'::`1'::dtor$0
text$x ENDS
PUBLIC main
; COMDAT pdata
pdata SEGMENT
$pdata$main DD imagerel $LN6
DD imagerel $LN6+42
DD imagerel $unwind$main
pdata ENDS
; COMDAT xdata
xdata SEGMENT
$unwind$main DD 010401H
DD 04204H
; Function compile flags: /Ogtpy
xdata ENDS
; COMDAT main
_TEXT SEGMENT
__formal$ = 48
__formal$ = 56
a$66206 = 64
main PROC ; COMDAT
; Line 13
$LN6:
sub rsp, 40 ; 00000028H
; Line 15
lea rcx, QWORD PTR a$66206[rsp]
call ?GetA@@YA?AUA@@XZ ; GetA
; Line 16
lea rdx, OFFSET FLAT:??_C@_0O@KLMCIIGF@Hello?0?5World?$CB?$AA@
xor r9d, r9d
xor r8d, r8d
xor ecx, ecx
call QWORD PTR __imp_MessageBoxA
; Line 18
xor eax, eax
; Line 19
add rsp, 40 ; 00000028H
ret 0
main ENDP
_TEXT ENDS
END
RB>Мне кажется странным, что для построения guard-объекта вызывается функция, часто пустая, которая сама может бросить исключение.
А что ты предлагаешь? Из-за того, что на одном из компиляторов, при non-default настройках, что-то не инлайнится — отказаться от type deduction и нормального синтаксиса?
SCOPE_EXIT { do(); };
Который от чисто языковой конструкции в языке D, отличается только ";"
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>MSVC2010SP1 Release: EP>/EHsc (default): EP>/EHs: EP>/EHa:
Ну, для чуть более нетривиального примера, наподобие SCOPE_EXIT, построение guard-а с помощью вызова функции происходит и при default /EHsc.
EP>Из-за того, что на одном из компиляторов, при non-default настройках, что-то не инлайнится — отказаться от type deduction и нормального синтаксиса? EP>Который от чисто языковой конструкции в языке D, отличается только ";"
Меня производительность интересует больше чем красота кода.
Вопрос был — пробовал кто-нибудь красиво обойти это ограничение MSVC, или всем пофиг?
Здравствуйте, rus blood, Вы писали:
RB>Ну, для чуть более нетривиального примера, наподобие SCOPE_EXIT, построение guard-а с помощью вызова функции происходит и при default /EHsc.
Код в студию!
EP>>Из-за того, что на одном из компиляторов, при non-default настройках, что-то не инлайнится — отказаться от type deduction и нормального синтаксиса? EP>>Который от чисто языковой конструкции в языке D, отличается только ";" RB>Меня производительность интересует больше чем красота кода.
Функция с type deduction, возвращающая guard, в случае с lambda — как раз и нужна для производительности — если без неё, то будет std::function, что ещё хуже.
Если тебе действительно нужна производительность, и не нужна lambda, то можешь сделать просто отдельный guard:
Здравствуйте, rus blood, Вы писали: RB>Меня производительность интересует больше чем красота кода. RB>Вопрос был — пробовал кто-нибудь красиво обойти это ограничение MSVC, или всем пофиг?
Здравствуйте, Evgeny.Panasyuk, Вы писали:
RB>>Под /EHa не оптимизирует, да и warning летит... RB>>А ты у себя /EHa не используешь?
EP>Я тебе уже показал