Unreachable code in constructor closing bracket

I am working on an application created using VC9, and I received a warning that I don’t quite understand: why is there a warning "unreachable code" in the closing bracket of the constructor?

Minimum test file to reproduce the problem:

__declspec(noreturn) void foo() { // Do something, then terminate the program } struct A { A() { foo(); } // d:\foo.cpp(7) : warning C4702: unreachable code }; int main() { A a; } 

This must be compiled with / W 4 to trigger a warning. Alternatively, you can compile with / we 4702 to cause an error when this warning is detected.

 d:\>cl /c /W4 foo.cpp Microsoft (R) C/C++ Optimizing Compiler Version 15.00.21022.08 for x64 Copyright (C) Microsoft Corporation. All rights reserved. foo.cpp d:\foo.cpp(7) : warning C4702: unreachable code 

Can someone explain what is inaccessible here? My best theory is that it is a destructor, but I would like a final answer.

If I want to make this code warning-clean, how can I achieve this? The best I can think of is to convert this to a compile-time error.

 struct A { private: A(); // No, you can't construct this! }; int main() { A a; } 

Edit: To clarify, terminating a program using the noreturn function usually does not cause an invalid warning code on the closing bracket containing this function call.

 __declspec(noreturn) void foo() { // Do something, then terminate the program } struct A { A() { } ~A() { foo(); } }; int main() { A a; } 

Results in:

 d:\>cl /c /W4 foo3.cpp Microsoft (R) C/C++ Optimizing Compiler Version 15.00.21022.08 for x64 Copyright (C) Microsoft Corporation. All rights reserved. foo3.cpp 
+7
source share
4 answers

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() { // Do something, then terminate the program } struct A { A() { foo(); } ~A() { } }; int main() { A a; } 

noreturn_destructor.cpp

 __declspec(noreturn) void foo() { // Do something, then terminate the program } struct A { A() { } ~A() { foo(); } }; int main() { A a; } 

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] 
+3
source

There are no destructors at the end of A::A() , so this is not a problem. What cannot be achieved is the actual construction of the object, which occurs after the constructor has completed its execution. Since it can never end, this code generated by the compiler is not available.

+2
source

This parameter points to declspec (noreturn) on foo. You tell the compiler that this function does not return. Therefore, the compiler issues a warning that your constructor will never complete.

+1
source

see http://msdn.microsoft.com/en-us/library/k6ktzx3s(v=vs.80).aspx

"This __declspec attribute tells the compiler that the function is not returning. As a result, the compiler knows that the code following the call to the __declspec (noreturn) function is not available."

A closing brace can generate code (for example, calling destructors) that will not be reached.

+1
source

All Articles