Why does rethrowing an exception discards the information given by 'what()'? - c++

I'm using MinGW gcc (or g++) 7.1.0 on Windows 10.
Normally, throwing an std::runtime_error shows information like this:
terminate called after throwing an instance of 'std::runtime_error'
what(): MESSAGE
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
But the following code only shows the last two lines, and the what() information is lost:
#include <stdexcept>
using namespace std;
int main() {
try {
throw runtime_error("MESSAGE");
} catch (...) {
throw;
}
}
So the code above only outputs:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
The same thing happens if I replace ... with const exception&, const runtime_error& (or without const, without &, or without both).
As I know, throw; rethrows the current caught exception. So why isn't what() shown?

What makes you think that rethrowing exception discards the information given by 'what()'? You never inspect what what() returns after rethrowing. This application has requested... message is shown because you uncaught exception caused program to be terminated. what() content is not supposed to be printed automatically.
You can print value return by what() without any problem:
#include <stdexcept>
#include <iostream>
int main()
{
try
{
try
{
throw ::std::runtime_error("MESSAGE");
}
catch (...)
{
throw;
}
}
catch(::std::exception const & exception)
{
::std::cout << exception.what() << ::std::endl;
}
}

Related

C++ thrown exception message not shown when running app from Windows CMD

If I run a simple app
#include <stdexcept>
int main() {
throw std::runtime_error("Hello World!");
}
with Windows CMD, the error message is not shown. How can I fix it?
Let's take a look at what throw does in C++ from the official Microsoft Docs.
In the C++ exception mechanism, control moves from the throw statement to the first catch statement that can handle the thrown type.
Note that this means throw does not actually output anything on its own — you'd have to catch it first, then output something. Also note that this means the throw will have to be surrounded by try if you want to do anything with the exception other than terminate the program (which throwing the exception will do on its own).
See below for an example of how to use throw properly.
#include <stdexcept>
#include <cstdio>
int main() {
try {
throw std::runtime_error("Hello World!");
} catch (const std::exception& e) {
puts(e.what());
}
}
The only thing guaranteed to happen when an exception escapes main is that the program stops.
To print the message of an exception you have to catch it and print the message
#include <stdexcept>
#include <cstdio>
int main()
{
try {
throw std::runtime_exception("Hello World!");
} catch (const std::exception& e) {
std::puts(e.what());
}
}

Why does this code produce different output from time to time?

Compiler:
➜ ~ /usr/bin/c++ --version
Apple clang version 11.0.0 (clang-1100.0.33.8)
Target: x86_64-apple-darwin19.0.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Code:
#include <iostream>
#include <exception>
#include <cstdlib>
void f() {
try {
throw std::runtime_error("Exception message.");
} catch(std::runtime_error& e) {
std::cout << e.what() << std::endl;
throw;
}
}
int main() {
using namespace std;
try {
f();
} catch(std::exception& e) {
cout << e.what() << endl;
terminate();
}
return EXIT_SUCCESS;
}
I found out that if i get rid of the "terminate()" in my catch it would work but i am not sure why that is?
There are three outputs that are produced randomly:
libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: Exception message.
Exception message.
Exception message.
Exception message.
libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: Exception message.
Exception message.
Exception message.
Exception message.
libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: Exception message.
P.S. Sorry, maybe for the incorrect question, I'm a beginner.
For starters, your regular cout print goes to stdout, but the "Terminating with ..." message goes to stderr.
What you observe stems from the fact that your terminal (or IDE) is reading these two output channels and presenting them in one place.
Depending on what algorithm your terminal/IDE uses to merge these two streams, it can happen that the stderr message appears in the places you notice.
If you instead point the streams toward the same file descriptor, your OS will take care of the merging. Run your program as follows:
./my_program 2>&1
Now your terminal will show the messages sequentially with no chance for accidental reordering.

How to automatically get the exception type and message from C++ programs on Mac?

From Linux I know that in case a C++ program throws an exception, the exception type and message are printed on the terminal while the program dies. On mac, however, the only thing you get is:
libc++abi.dylib: terminate called throwing an exception
Abort trap: 6
Of course I could run the program in a debugger, but that's usually much more overhead just to see the exception type and message.
Is there any way to enable exception type and message printing on mac with any magic command?
Edit: I know what the correct way is to handle such situations with exception handling. It is more out of curiosity to find out whether the linux behavior can be reproduced on mac.
If you want to guarantee the information of a C++ exception is printed to the console you can add a try/catch block in main() like below.
#include <exception>
#include <iostream>
int main(int argc, char* argv[])
{
try { return mymain(argc, argv); }
catch(std::exception& e)
{
std::cout << "Unhandled exception thrown: " << e.what() << std::endl;
}
}

Exception Handling - set_unexpected() not able to call

#include "iostream"
#include "conio.h"
#include "exception"
#include "cstdlib"
using namespace std;
void myunexpected ()
{
cerr << "unexpected called\n";
throw 0; // throws int (in exception-specification)
}
void myfunction () throw (int)
{
throw 'x'; // throws char (not in exception-specification)
}
int main (void)
{
set_unexpected (myunexpected);
try
{
myfunction();
}
catch (int) { cerr << "caught int\n"; }
catch (...) { cerr << "caught other exception (non-compliant compiler?)\n"; }
getch();
return 0;
}
Output(When executed on Visual studio 2008):
caught other exception (non-compliant compiler?)
But, I was expecting the output to be:
unexpected called
caught int
NOTE: I executed this program on Visual Studio 2008.
Yes, as per the Standard the output should be[#1]:
unexpected called
caught int
gcc gives accurate result.
Note that, MSVC is notoriously buggy w.r.t handling exception specifications. Exception specifications are considered a failed experiment.
AFAIK, MSVC does not implement exception specifications, except for the empty ones (throw()/nothrow)
C++03 Standard:
[#1] 15.5.2 The unexpected() function [except.unexpected]
The unexpected() function shall not return, but it can throw (or re-throw) an exception. If it throws a new exception which is allowed by the exception specification which previously was violated, then the search for another handler will continue at the call of the function whose exception specification was violated....

Question about Exceptions

I was just playing around with exceptions in the visual studio and with the above code I was expecting that since my exception specification doesn't mention anything the bad_exception should have been thrown. But what actually happens is the exception gets caught by the appropriate handler. Why so? Am i missing some setting or something in the IDE?
While i got stuck at above mentioned, Actually I was trying to find answer to the question,If i have a exception blank specification then what gets called?
the unexpected() method or a *bad_exception* will be thrown and if both in what order?
Here's the code.
#include "stdafx.h"
#include <stdio.h>
#include <exception>
#include <iostream>
using namespace std;
class A
{
public:
int i;
};
void myunexpected ()
{
cerr << "unexpected called\n";
}
void doSomething(void) throw();
void doSomething(void) throw()
{
A obj;
obj.i= 100;
throw obj;
}
int _tmain(int argc, _TCHAR* argv[])
{
set_unexpected (myunexpected);
try
{
doSomething();
}
catch (bad_exception be)
{
puts("Caught something");
}
catch (A &obj)
{
puts("Caught Integer");
}
return 0;
}
Regarding exception specification, Visual Studio is not standard-conforming.
While the empty exception specification is somewhat useful (but, as said, not properly implemented by VS), in general exception specifications are seen as an experiment that failed.
Basically, exception specifications are almost useless and in many compilers implemented different to what the standard states. Look at your compiler documentation for more information.
http://msdn.microsoft.com/en-us/library/wfa0edys(VS.80).aspx
I can imagine that this means in particular that the VS compiler will use the exception specification to avoid generating code required for stack unwinding and that in the event of an exception actually being thrown you will end up with undefined behavior.