#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....
Related
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());
}
}
In this simple use of C++ contracts, I get the error: no type named 'fail_fast' in namespace 'gsl'. Will try block throw the fast_fail exception or some other exception?
#define GSL_THROW_ON_CONTRACT_VIOLATION
#include <gsl/gsl>
#include <iostream>
int main(void)
{
try {
Expects(false);
}
catch(const gsl::fail_fast &e) {
std::cout << "exception: " << e.what() << '\n';
}
}
GSL_THROW_ON_CONTRACT_VIOLATION and gsl::fast_fail were removed from the Microsoft GSL starting with release v3.0.0. All contract violations result in a call to std::terminate unless you are building in kernel mode for MSVC where it invokes __fastfail.
Header file gsl_assert.h only defines gsl::fail_fast exception with GSL_THROW_ON_CONTRACT_VIOLATION defined. So it compiles now? – Serve Laurijssen
There was a period of time where gsl::fast_fail was defined only when GSL_THROW_ON_CONTRACT_VIOLATION was defined, however that was identified in #267 and subsequently fixed in #268.
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;
}
}
I have read that one can call std::set_terminate() to use own function as global exception handler, which catches all unhandled exceptions.
Simplified code of my program:
#include <exception>
#include <stdexcept>
#include <iostream>
void my_terminate_handler()
{
std::cerr << "Terminate handler" << std::endl;
std::cin.get();
std::abort();
}
int main()
{
std::set_terminate(my_terminate_handler);
int i = 1;
i--;
std::cout << 1/i << std::endl;
return 0;
}
Why my_terminate_handler() never invoked? Both in VC++ 2013, 2015 RC and gcc++-4.8.
The terminate handler will be called if the program calls terminate. This can happen for various reasons - including an uncaught exception - but division by zero isn't one of those reasons. That gives undefined behaviour; typically, it raises a signal (not a C++ exception), and you'd need to install a signal handler, not a terminate handler, to catch that.
Because there is no uncaught exception in your code. Add one and it gets executed:
#include <exception>
#include <stdexcept>
#include <iostream>
void my_terminate_handler()
{
std::cerr << "Terminate handler" << std::endl;
}
int main()
{
std::set_terminate(my_terminate_handler);
throw "cake";
}
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.