Gorpek on the right track. I created two similar test cases, compiled them and parsed them, and I think I understood the main reason: the constructor always generates a return statement implicitly, and this return statement is not available due to the noreturn function.
noreturn_constructor.cpp
__declspec(noreturn) void foo() {
noreturn_destructor.cpp
__declspec(noreturn) void foo() {
diff -u * .disasm
--- noreturn_constructor.disasm 2012-05-30 11:15:02.000000000 -0400 +++ noreturn_destructor.disasm 2012-05-30 11:15:08.000000000 -0400 @@ -2,7 +2,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. -Dump of file noreturn_constructor.obj +Dump of file noreturn_destructor.obj File Type: COFF OBJECT @@ -35,15 +35,15 @@ ??0A@ @ QEAA@XZ (public: __cdecl A::A(void)): 0000000000000000: 48 89 4C 24 08 mov qword ptr [rsp+8],rcx - 0000000000000005: 48 83 EC 28 sub rsp,28h - 0000000000000009: E8 00 00 00 00 call ?foo@ @YAXXZ - 000000000000000E: 48 8B 44 24 30 mov rax,qword ptr [rsp+30h] - 0000000000000013: 48 83 C4 28 add rsp,28h - 0000000000000017: C3 ret + 0000000000000005: 48 8B 44 24 08 mov rax,qword ptr [rsp+8] + 000000000000000A: C3 ret ??1A@ @ QEAA@XZ (public: __cdecl A::~A(void)): 0000000000000000: 48 89 4C 24 08 mov qword ptr [rsp+8],rcx - 0000000000000005: C3 ret + 0000000000000005: 48 83 EC 28 sub rsp,28h + 0000000000000009: E8 00 00 00 00 call ?foo@ @YAXXZ + 000000000000000E: 48 83 C4 28 add rsp,28h + 0000000000000012: C3 ret Summary
Unreachable code is the implicit return statement that is generated in the constructor, but not the destructor:
- 000000000000000E: 48 8B 44 24 30 mov rax,qword ptr [rsp+30h] + 0000000000000005: 48 8B 44 24 08 mov rax,qword ptr [rsp+8]
mrkj
source share