C ++: Can "try {foo ();} catch (...) {throw;}" be optimized for "foo ();"?

In C ++, the following code is given

try { foo(); } catch (...) { throw; } 

semantically identical to a simple call to foo like this?

 foo(); 

If so, can I expect the modern compiler to escape the first version for the second version (enabled when compiling with optimizations)?

In other words, if I compile this code with NDEBUG and optimizations enabled

 try { foo(); } catch (...) { assert(some_check()); throw; } 

can i assume that it should never be slower than this ugly version

 #ifndef NDEBUG try { #endif foo(); #ifndef NDEBUG } catch (...) { assert(some_check()); throw; } #endif 
+6
source share
1 answer

No, they are not equivalent.

Whether the stack is deployed when there is no exception handler is determined by the implementation ([except.handle] p9). When a handler exists, but it just throws the exception, the stack should be deployed, at least until the exception is thrown again.

I.e:

 struct S { ~S(); }; void foo() { S s; throw 0; } int main() { try { foo(); } catch(...) { throw; } } 

This should call the s destructor. When try { ... } catch (...) { throw; } try { ... } catch (...) { throw; } is deleted, you no longer need to call the s destructor.

This is possible even depending on what the destructor s does so that execution never reaches the exception throw again, adding, for example:

 #include <stdlib.h> S::~S() { exit(0); } 

Now the program should run successfully, but when you delete try { ... } catch (...) { throw; } try { ... } catch (...) { throw; } , which is no longer required, and may crash in real systems.

+3
source

All Articles