I can't find a way to actually enable c++ exception handling in visual studio 2017. Maybe I am missing something trivial. I've searched a lot and found nothing that solves this simple issue.
Even this simple code does not act as expected:
#include <iostream>
//#include <exception>
int main(int argc, char *argv[])
{
try
{
int j = 0;
int i = 5 / j;
std::cout << "i value = " << i << "\n";
std::cout << "this line was actually reached\n";
}
catch (...)
//catch (std::exception e)
{
std::cout << "Exception caught!\n";
return -1;
}
std::cout << "Exception was NOT caught!\n";
std::cin.get();
}
When I execute this simple code the program crashes, like the exception is never caught, I tried also with std::exception variant, and i get the same result.
The division by zero is just an example, I could have wrote also something like this:
ExampleClass* pClassPointer = null;
pClassPointer->doSomething();
and expected that a nullpointer exception was automatically thrown and captured by the catch(...) clause.
Just as an information, I added the line:
std::cout << "i value = " << i << "\n";"
otherwise the compiler optimization would have skipped most of the code and the result (in RELEASE mode) was:
this line was actually reached
Exception was NOT caught!
In the properties page of the project, in the option "Enable C++ Exceptions" I have the value: "Yes (/EHsc)", so I think exceptions should be actually enabled.
Am I missing something?
Thank you in advance.
Andrea
---- Edit
I actually just found out that changing the option "Enable C++ Exceptions" with the value "Yes with SEH Exceptions (/EHa)" instead of "Yes (/EHsc)" allows to capture access violation and divide by zero errors in the catch(...) clause.
I've also found very useful information about this subject and whether or not is a good idea to catch those type of exceptions in the replies to this other thread:
Catching access violation exceptions?
In C++ you throw an exception, and, having done that, you can catch it. If you didn't throw it, you can't catch it.
Confusingly, there are many kinds of errors that are generically referred to as "exceptions". This is especially true in floating-point math, where anything that goes wrong is a "floating-point exception". It's the same word, but those exceptions are not C++ exceptions, and you cannot reliably catch them.
In general, when something goes wrong in your program you get undefined behavior, that is, the language definition does not tell you what the program does. So you're on your own: if your compiler documents what it does when a program divides an integer value by 0, then you can rely on that behavior. If not, don't count on anything.
#include <iostream>
int main(int argc, char *argv[])
{
try
{
int j = 0;
int i ;
if(j==0)
throw j; // you have throw some variable or atleast use throw for your
//catch to work
std::cout << "i value = " << j/5<< "\n";
std::cout << "this line was actually reached\n";
}
catch (int e) /*catch will work only if the data type of argument matches with the thrown variable's data type if it does not then the compiler's default catch will run*/
{
std::cout << "Exception caught!\n";
return -1;
}
std::cout << "Exception was NOT caught!\n";
std::cin.get();
}
if u still have any questions ask in comments!
Related
I am a bit confused on where I should throw an exception and where I should catch it. Right now I am throwing an invalid_argument as soon as someone creates a book with an invalid page.
In my main function I am then creating a book with an invalid page and I am catching that exception and writing out the message. Is this how you are supposed to do it? Because right now I am only catching one single instance of a book. If I tried to create another book outside the try catch block with an invalid page I woudnt be able to catch it. Is this really necessary? Is this how I'm supposed to handle exceptions?
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
class Book
{
public:
string title {};
string author {};
int pages {};
int readers {};
Book(string const& t, string const& a, int const p)
: title{t}, author{a}, pages{p}, readers{0}
{
if (pages <= 0)
throw invalid_argument ("Invalid page!");
}
void print() const
{
cout << "Title: " << title << "\nAuthor: " << author
<< "\nPages: " << pages << "\nReaders: " << readers << endl;
}
};
int main()
{
try
{
Book book_1("Harry Potter", "JK Rowling", 0);
}
catch(const exception& e)
{
cerr << "Exception: " << e.what() << endl;
}
//book_1.print();
return 0;
}
Yes, if you call a function that may throw an exception, at some point, you will need to handle it. The way to do it is to catch the exception.
Is it really necessary?
Well it depends. If in your case you ensure that you won't create your objects with invalid arguments, you don't need to catch an exception that'll never be raised.
Exception handling is only required when you don't know (you have no guarantee), for example when the page parameter is given from a user input, a file or anything that is unknown/not predictable/not controlled by the code base.
That being said, in your case you can do even better, just replace:
int pages;
with:
unsigned int pages;
And then it would not be possible to give an invalid number anymore. Which means you can completely remove the exception handling off your code.
The above proposal didn't take into account that 0 is considered invalid as well.
You should catch and handle the exception where it makes sense for the program.
First of all, your program always throws the exception independent of input, because the 0 is hard-coded. This doesn't seem to be a use case for an exception. This seems to be a logic error and so it should be considered a bug that needs fixing. Why should it make sense to try to create a guaranteed invalid book?
But let's suppose the number of pages is given by user input. Then the next issue would be that you can't print a book that failed to be created. So book_1.print(); must be part of the try block.
Let's suppose you have a second book book_2, also created from input from the user. You need to ask yourself then whether it makes sense for the program logic to continue creating and using the second book if creating the first one failed.
If failing to create the first book means that there is no point in continuing with the second book, then just put everything in one try block, e.g.:
try
{
Book book_1(/*...*/);
book_1.print();
Book book_2(/*...*/);
book_2.print();
}
catch(const exception& e)
{
cerr << "Exception: " << e.what() << endl;
}
When either of the book creations fail, the program will continue executing in the catch handler and then after it, skipping over the rest of the book creations and printing. But if book_1 didn't throw on construction, then it will be printed before book_2 is "checked".
Maybe you would want
try
{
Book book_1(/*...*/);
Book book_2(/*...*/);
book_1.print();
book_2.print();
}
catch(const exception& e)
{
cerr << "Exception: " << e.what() << endl;
}
With this the program will not print any book if creation of either book fails.
If it does make sense for the program to continue execution if creation of the first book failed, then use two try/catch statements to handle the errors individually:
try
{
Book book_1(/*...*/);
book_1.print();
}
catch(const exception& e)
{
cerr << "Exception: " << e.what() << endl;
}
try
{
Book book_2(/*...*/);
book_2.print();
}
catch(const exception& e)
{
cerr << "Exception: " << e.what() << endl;
}
You might want to consider using a function or arrays and loops to make this less redundant, for example if the goal is to just repeatedly take user input, create a book and then print it, a simple loop will be helpful:
while(true)
{
try
{
/* take user input here */
if(/* some exit condition */)
{
break;
}
Book book(/* arguments from user input */);
book.print();
}
catch(const exception& e)
{
cerr << "Exception: " << e.what() << endl;
}
}
This loop will run until the exit condition is satisfied. If any standard exception (from book creation or the input operation) is thrown, the exception message will be printed and the loop continues anew.
(As an additional note: In all of the examples above all exceptions inherited from std::exception thrown in the try blocks will be caught. This means not only the invalid_argument exception from the book creation, but e.g. any exception thrown by .print() or the input handling. You may not want to handle these the same way as the invalid book creation. For example an exception from input operations could mean that there is no way for the program to continue the loop. Therefore it makes sense to use a custom class (maybe inherited from std::invalid_argument) for the throw in Book's constructor and catch only that. This way you can handle the invalid book creation specifically.)
<C++>In exception handling, do you need to know what exception and where an exception is going to occur? Can you make a code which will print and notify us that an exception occurred somewhere in the program. I mean I have a program in which I don't know if an exception will occur or not, if one was to occur, then it will print to notify us.
Exception handling is something you should design for, and in fact it works very well together with RAII (https://en.cppreference.com/w/cpp/language/raii).
(Notr On embedded platforms using exceptions, is not so popular because of some runtime overhead). What I personally like about exceptions is that it separates error handling from the normal program flow (there will be hardly any if then else checks when done right)
// Exception handling should be part of your overal design.And many standard library functions can throw exceptions, It is always up to you where you handle them.
#include <iostream>
#include <string>
#include <stdexcept>
int get_int_with_local_exception_handling()
{
do
{
try
{
std::cout << "Input an integer (local exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
// stoi is a function that can throw exceptions
// look at the documentation https://en.cppreference.com/w/cpp/string/basic_string/stol
// and look for exceptions.
//
int value = std::stoi(input);
// if input was ok, no exception was thrown so we can return the value to the client.
return value;
}
// catch by const reference, it avoids copies of the exception
// and makes sure you cannot change the content
catch (const std::invalid_argument& e)
{
// std::exceptions always have a what function with readable info
std::cout << "handling std::invalid_argument, " << e.what() << "\n";
}
catch (const std::out_of_range& e)
{
std::cout << "handling std::out_of_range, " << e.what() << "\n";
}
} while (true);
}
int get_int_no_exception_handling()
{
std::cout << "Input an integer (without exception handling, enter a text for exception): ";
std::string input;
std::cin >> input;
int value = std::stoi(input);
return value;
}
int main()
{
try
{
// this function shows you can handle exceptions locally
// to keep program running
auto value1 = get_int_with_local_exception_handling();
std::cout << "your for input was : " << value1 << "\n";
// this function shows that exceptions can be thrown without
// catching, but then the end up on the next exception handler
// on the stack, which in this case is the one in main
auto value2 = get_int_no_exception_handling();
std::cout << "your input was : " << value1 << "\n";
return 0;
}
catch (const std::exception& e)
{
std::cout << "Unhandled exception caught, program terminating : " << e.what() << "\n";
return -1;
}
catch (...)
{
std::cout << "Unknown, and unhandled exception caught, program terminating\n";
}
}
Yes and no.
No, because any exception thrown via throw some_exception; can be catched via catch(...).
Yes, because catch(...) is not very useful. You only know that there was an excpetion but not more.
Typically exceptions carry information on the cause that you want to use in the catch. Only as a last resort or when you need to make abolutely sure not to miss any excpetion you should use catch(...):
try {
might_throw_unknown_exceptions();
} catch(std::exception& err) {
std::cout << "there was a runtime error: " << err.what();
} catch(...) {
std::cout << "an unknown excpetion was thrown.";
}
The C++ standard library uses inheritance only sparingly. Exceptions is only place where it is used extensively: All standard exceptions inherit from std::exception and it is good practice to inherit also custom exceptions from it.
I have been learning c++ recently and while working on exceptions, I came across something that confuses me. I threw a string exception and added multiple catch blocks to see how it works, and for some reason, the string exception is being caught in the int catch block. This is puzzling me and I cant see to find reasons why it would do it.
FYI, I am using GCC v 5.3.0
So, I was expecting the following message on the console.
String exception occurred: Something else went wrong
But instead, I got the following message.
Int exception occurred: 14947880
So I tried switching the order of the catch blocks and placed the string catch block on the top, and I got the string exception message. Could somebody please explain a reason why this is happening? It seems whatever catch block is in the top is being caught first.
I don't think this is the correct behavior and that the string exception block should be executed, but if I am wrong, please correct me. Thanks for taking time to look at this.
#include <iostream>
using namespace std;
void MightGoWrong()
{
bool error = true;
if (error)
{
throw string("Something else went wrong");
}
}
/**
* Output on console: Int exception occurred: 14947880
*/
int main() {
try
{
MightGoWrong();
}
// If string or char pointer catch block goes to top, that block will execute
catch (int e)
{
cout << "Int exception occurred: " << e << endl;
}
catch (string &e)
{
cout << "String exception occurred: " << e << endl;
}
catch (char const * e)
{
cout << "Char exception occurred: " << e << endl;
}
return 0;
}
My large application has this structure:
int main()
{
try {
...
} catch (std::exception& e) {
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
return 1;
}
}
Deep inside the call stack, various objects check their internal state, throwing std::runtime_exception if they detect something bad. The all-inclusive exception handler catches it, prints some moderately useful info and terminates the program.
However, when I am debugging under MS Visual Studio, I could benefit from not having any exception handler: Visual Studio has its own, very useful, handler, which stops my application at the place where the exception is thrown, so I can examine what went wrong.
How can I do the catching of my exceptions conditionally?
I tried the following:
try {
...
} catch (std::exception& e) {
if (IsDebuggerPresent())
throw;
else
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
}
This gave a weird result: Visual Studio caught the exception that was rethrown and showed me the stack trace at the point where the exception was thrown. However, all objects in my application were apparently destructed, and I couldn't see e.g. local or member variables.
I could make the exception handler conditional on a compilation flag:
#ifdef NDEBUG
try {
#endif
...
#ifdef NDEBUG
} catch (std::exception& e) {
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
}
#endif
but this is inconvenient because I have to recompile everything if I want to debug it.
So, how can I make my exception handling conditional (depending on a command-line argument, for example)?
So, how can I make my exception handling conditional (depending on a command-line argument, for example)?
By writing the code for it :o]
Consider this original code:
int main()
{
try {
run_the_application(); // this part different than your example
} catch (std::exception& e) {
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
return 1;
}
}
New code:
template<typename F>
int fast_run(F functor) { functor(); return EXIT_SUCCESS; }
template<typename F>
int safe_run(F functor)
{
try {
functor();
} catch (std::exception& e) {
std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
template<typename F>
int run(const std::vector<std::string>& args, F functor)
{
using namespace std;
if(end(args) != find(begin(args), end(args), "/d"))
return fast_run(functor);
else
return safe_run(functor);
}
int main(int argc, char** argv)
{
const std::vector<std::string> args{ argv, argv + argc };
return run(args, run_the_application);
}
As suggested by CompuChip, Visual Studio can break execution when throwing an exception, not only when catching an uncaught one!
To enable this (in Visual Studio 2012):
In the menu, go Debug -> Exceptions
In the opened window, tick the "Thrown" box for all C++ exceptions (ticking just std::exception is not enough - I don't know why)
Run your program
This is something far from great but you can define command line parameter in CMake (assuming you use it):
-DCATCH_ALL=true
Then, in CMakelists.txt, you can propagate this to C++ macro:
if (CATCH_ALL)
message("Some exceptions with not be caught")
add_compile_definitions(CATCH_ALL)
else ()
message("Trying to catch more exceptions to provide better diagnostics")
endif ()
And finally, in the code:
#ifdef CATCH_ALL
try {
#endif
a = big_problematic_algorithm(problematic_parameter);
#ifdef CATCH_ALL
} catch (const std::exception &err) {
LOGF(WARN, "Crashed for the parameter %s: %s", problematic_parameter.c_str(), err.what());
}
#endif
It is rather clumsy but OK if not used too often, only somewhere at very high level (handling a complete web request, user action, file to process or the like). It allows to provide better diagnostic logs if the crash happens not while running in IDE, also to recover if you throw this exception yourself so know how.
It is possible to configure IDE to set the CMake parameter. When building on the integration server or from the command line, this is just not done activating additional handling of exceptions.
I have a sample code to modify and throw exception handling. The problem is even after I threw an exception, the code still returns a random 0. I have spent some time trying to figure out why I still have a 0 returned but I could not find the answer. Does anyone have an idea why the code behaves like this?
#include <stdexcept>
#include <iostream>
#include <string>
using namespace std;
struct myException_Product_Not_Found : exception
{
virtual const char* what() const throw() {
return "Product not found";
}
} myExcept_Prod_Not_Found;
int getProductID(int ids[], string names[], int numProducts, string target) {
for (int i=0; i<numProducts; i++) {
if(names[i] == target)
return ids[i];
}
try {
throw myExcept_Prod_Not_Found;
}
catch (exception& e) {
cout<<e.what()<<endl;
}
}
// Sample code to test the getProductID function
int main() {
int productIds[] = {4,5,8,10,13};
string products[] = {"computer","flash drive","mouse","printer","camera"};
cout << getProductID(productIds, products, 5, "computer") << endl;
cout << getProductID(productIds, products, 5, "laptop") << endl;
cout << getProductID(productIds, products, 5, "printer") << endl;
return 0;
}
getProductID doesn't throw an exception. You catch the exception you do throw before getProductID has a chance to throw it. As such, you return ... well, nothing. The functions ends without you calling return.
If you had turned on your compiler's warnings* (as should should be doing), the compiler should warn with a message like control reaches end of non-void function. g++ appears to return zero in this instance, but returning zero is probably undefined behaviour.
If you want a function to throw an exception, don't catch the exception you've thrown inside of the function. Move the catch to the outside.
int getProductID(...) {
...
throw myExcept_Prod_Not_Found;
}
string product = "computer";
try {
cout << getProductID(productIds, products, 5, product) << endl;
} catch (exception& e) {
cout << "Can't find product id for " << product << ": " << e.what() << endl;
}
* — To turn on warnings in g++, -Wall is a good starting point. #Tomalak Geret'kal suggests -Wall -Wextra -std=c++98 -pedantic or -Wall -Wextra -std=c++0x -pedantic.
try {
throw myExcept_Prod_Not_Found;
}
catch (exception& e) {
cout<<e.what()<<endl;
}
Here you're throwing an exception and then immediately catching it. The exception message is output to console and then execution of your function continues as normal... except you have no value to return.
So, the result of that function call is unspecified, and you're seeing some arbitrary rubbish from memory as well as invoking undefined behaviour.
Instead, just let the exception propogate right up the callstack by not catching it: it'll lead your program to terminate (possibly without actually unrolling, incidentally):
throw myExcept_Prod_Not_Found;