Home Dashboard Directory Help
Search

Empty C++ destructors prevent optimization by Krishty


Status: 

Active


9
0
Sign in
to vote
Type: Bug
ID: 560640
Opened: 5/21/2010 4:57:08 AM
Access Restriction: Public
0
Workaround(s)
view
1
User(s) can reproduce this bug

Description

A C++ class with an empty destructor does not get as optimized as a class with a compiler-generated destructor does. This problem is very hard to spot when investigating why certain code is slower than expected.
Details
Sign in to post a comment.
Posted by Microsoft on 8/10/2010 at 5:34 PM
Krishty,

To follow up, we are already aware of this issue. We are working improving our inlining decisions in the presence of EH for a future release of Visual C++.

Thanks,
~Pete
Windows C++ SDET
Posted by Microsoft on 8/10/2010 at 5:13 PM
Krishty,

I have reproduced the issue successfully on my side. I have forwarded the issue to the appropriate engineer to see what we can do about it.

Thanks,
~Pete Steijn
Windows C++ SDET
Posted by Krishty on 5/27/2010 at 8:08 AM
Okay, that was fast :) It's the exception handling. With /EHsc, it's reproducable.

As far as I know, the compiler is unable to inline functions if they return unwindable objects by value (at least that's what MSDN says for warning C4714). It seems like Vector is classified unwindable although its destructor is empty - but a compiler-generated destructor, on the other hand, is fine for the optimizer ...

Maybe the ticket should be renamed to "objects are unwinded although their destructors have no effect" or something like that ...
Posted by Krishty on 5/27/2010 at 7:39 AM
Okay, this is weird. I can definitely reproduce it here:
new project -> console application -> empty project -> added foo.cpp -> inserted code (added #include <iostream>, sry for that) -> chose Release Win32 -> adjusted Configuration Properties -> C/C++ -> Optimization -> Optimization / Inline Function Expansion -> added /FAsc to command line (/GL and /ltcg are enabled by default)

It compiled to http://pastebin.com/09gC8xbs, where operator + is *not* inlined. After removing "~Vector() { }", it compiled to http://pastebin.com/rixe139q, which is optimal (also, your result).

Seems like one of the default project settings is interfering ...? I never compiled directly from command before, but I'm going to give it a try this evening. Hope I can find out what's making the difference.
Posted by Microsoft on 5/26/2010 at 4:35 PM
Sorry to keep coming back to you; it's not reproducing for me. Here's the code I get from the listing for main. Line ;21 is the inlined code for the vector add, no call, just fld/fadd.

Unless you're compiling /arch:SSE2 or /LTCG:PGO or some other flag I'm not using? I ran:

cl /Ox /Ob2 /GL /FAsc foo.cpp /link /ltcg

I also added #include <iostream> to the test, but nothing more. With other include files YMMV.

_TEXT    SEGMENT
_A$ = -32                        ; size = 4
_B$ = -28                        ; size = 4
_C$ = -24                        ; size = 4
_D$ = -20                        ; size = 4
_Result$ = -16                        ; size = 16
_main    PROC

; 17 : int main() {

00000    55         push     ebp
00001    8b ec         mov     ebp, esp
00003    83 e4 f8     and     esp, -8            ; fffffff8H
00006    83 ec 20     sub     esp, 32            ; 00000020H

; 18 :
; 19 :    float A, B, C, D;
; 20 :    ::std::cin >> A >> B >> C >> D;

00009    8d 44 24 0c     lea     eax, DWORD PTR _D$[esp+32]
0000d    50         push     eax
0000e    51         push     ecx
0000f    8d 4c 24 10     lea     ecx, DWORD PTR _C$[esp+40]
00013    51         push     ecx
00014    51         push     ecx
00015    8d 54 24 14     lea     edx, DWORD PTR _B$[esp+48]
00019    52         push     edx
0001a    51         push     ecx
0001b    8d 44 24 18     lea     eax, DWORD PTR _A$[esp+56]
0001f    50         push     eax
00020    68 00 00 00 00     push     OFFSET ?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A ; std::cin
00025    e8 00 00 00 00     call     ??5?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV01@AAM@Z ; std::basic_istream<char,std::char_traits<char> >::operator>>
0002a    83 c4 04     add     esp, 4
0002d    50         push     eax
0002e    e8 00 00 00 00     call     ??5?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV01@AAM@Z ; std::basic_istream<char,std::char_traits<char> >::operator>>
00033    83 c4 04     add     esp, 4
00036    50         push     eax
00037    e8 00 00 00 00     call     ??5?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV01@AAM@Z ; std::basic_istream<char,std::char_traits<char> >::operator>>
0003c    83 c4 04     add     esp, 4
0003f    50         push     eax
00040    e8 00 00 00 00     call     ??5?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV01@AAM@Z ; std::basic_istream<char,std::char_traits<char> >::operator>>

; 21 :    Vector const Result = Vector(A, B, C, D) + Vector(0.0f, 1.0f, 2.0f, 3.0f);

00045    d9 04 24     fld     DWORD PTR _A$[esp+32]
00048    dc 05 00 00 00
    00         fadd     QWORD PTR __real@0000000000000000

; 22 :    ::std::cout << Result.A << Result.B << Result.C << Result.D;

0004e    83 ec 1c     sub     esp, 28            ; 0000001cH
00051    d9 5c 24 2c     fstp     DWORD PTR _Result$[esp+60]
00055    d9 44 24 20     fld     DWORD PTR _B$[esp+60]
00059    dc 05 00 00 00
    00         fadd     QWORD PTR __real@3ff0000000000000
0005f    d9 5c 24 30     fstp     DWORD PTR _Result$[esp+64]
00063    d9 44 24 24     fld     DWORD PTR _C$[esp+60]
00067    dc 05 00 00 00
    00         fadd     QWORD PTR __real@4000000000000000
0006d    d9 5c 24 34     fstp     DWORD PTR _Result$[esp+68]
00071    d9 44 24 28     fld     DWORD PTR _D$[esp+60]
00075    dc 05 00 00 00
    00         fadd     QWORD PTR __real@4008000000000000
0007b    d9 5c 24 38     fstp     DWORD PTR _Result$[esp+72]
0007f    d9 44 24 38     fld     DWORD PTR _Result$[esp+72]
00083    d9 5c 24 18     fstp     DWORD PTR [esp+24]
00087    d9 44 24 34     fld     DWORD PTR _Result$[esp+68]
0008b    d9 5c 24 10     fstp     DWORD PTR [esp+16]
0008f    d9 44 24 30     fld     DWORD PTR _Result$[esp+64]
00093    d9 5c 24 08     fstp     DWORD PTR [esp+8]
00097    d9 44 24 2c     fld     DWORD PTR _Result$[esp+60]
0009b    d9 1c 24     fstp     DWORD PTR [esp]
0009e    68 00 00 00 00     push     OFFSET ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout
000a3    e8 00 00 00 00     call     ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@M@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
000a8    83 c4 04     add     esp, 4
000ab    50         push     eax
000ac    e8 00 00 00 00     call     ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@M@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
000b1    83 c4 04     add     esp, 4
000b4    50         push     eax
000b5    e8 00 00 00 00     call     ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@M@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
000ba    83 c4 04     add     esp, 4
000bd    50         push     eax
000be    e8 00 00 00 00     call     ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@M@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<

; 23 :
; 24 :    return 0;

000c3    33 c0         xor     eax, eax

; 25 : }

000c5    8b e5         mov     esp, ebp
000c7    5d         pop     ebp
000c8    c3         ret     0
_main    ENDP
_TEXT    ENDS
Posted by Krishty on 5/25/2010 at 2:57 AM
Yes I forgot to say, I'm compiling for x86.

Btw, the bug could be reproduced in VCpp 2008 and VCpp 2005, too.
Posted by Microsoft on 5/24/2010 at 12:39 PM
Hi, are you compiling for x86 or x64? I'm not seeing that info in the bug, but that doesn't necessarily mean you didn't enter it...

Thanks - VS Product Team triage

PS (just fyi) /Ox implies /Ob2
Posted by Microsoft on 5/23/2010 at 6:54 PM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.

Thank you
Posted by Microsoft on 5/21/2010 at 5:02 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.