I'm compiling the following code with Visual C++ 2017 (C++17 features are enabled)
int main() {
try {
// loot is some library that is linked as a dll
auto game = loot::CreateGameHandle(loot::GameType::fonv, "c:\\something\\invalid", "C:\\something\\invalid");
// throw std::invalid_argument("this works as expected");
}
catch (const std::exception &e) {
std::cout << "caught as exception " << e.what() << std::endl;
}
catch (const std::invalid_argument &e) {
std::cout << "caught as invalid_argument " << e.what() << std::endl;
}
catch (...) {
std::cout << "caught by ..." << std::endl;
}
}
The compiler reports, as expected:
warning C4286: 'const std::invalid_argument &': is caught by base class ('const stdext::exception &') on line 8
However, the application output is
caught as invalid_argument Given game path "c:\something\invalid" does not resolve to a valid directory.
And it's not just changing the catch order or something, if I remove the last 2 catch blocks, the application crashes because of the unhandled exception.
How is that even possible? I'm assuming this is somehow related to compiler settings that make my std::exception be a different type from the one std::invalid_argument inside the library inherits from - but why then is my std::invalid_argument the same type as theirs?
Is there a way to fix this? Because that library throws a lot of different exception types and I can't really catch each one individually.
Bloody hell, sorry for this.
It turns out the build system I was using added _HAS_EXCEPTIONS=0 to the preprocessor definitions. That's what's causing this.
Related
I am trying to handle an exception in Visual Studio Community 2019, note that I am not sure if I have an error with my settings or it is because of my code.
The exception that I am trying to handle is out_of_range. In order to do it I put it within a try block and catch, but I am unable to handle.
When the program runs it prompts a window : Debug Assertion Failed!
Expression vector subscript out of range
#include <iostream>
#include <vector>
#include <stdexcept>
using namespace std;
int main() {
try {
cout << "throwing exception: \n";
throw 1;
}
catch (int i) {
cout << "exception happended!\n";
}
cout << "out of exception\n";
vector<int> v;
try {
cout << "throwing exception2: \n";
v[2];
}
catch (out_of_range e) {
cout << "Exception out of range\n";
cout << e.what();
}
catch (exception& d) {
cout << "General Exception\n";
cout << d.what();
}
catch (...) {
cout << "special excpetinon\n";
}
cout << "Exception handled!";
}
The first exception I am able to handle and the programs continues whereas in the second one the program is stopped and its showing the window Error.
I run the program in debug mode, with the default settings:
I would like to handle the second exception the same way as the first one.
Thanks!
Debug Assertion Failed! Expression vector subscript out of range
isn't an exception. That's the debugger telling you your program went out of bounds and stopped you so you could inspect the program and learn how it happened in order to prevent the program going out of bounds. You can't catch this. You need to fix the bug that allowed the program to access invalid memory.
C++ has a policy of not making a program pay for anything that isn't explicitly asked for. In this case, the checking necessary to allow a catch-able exception to be thrown slows down the program, so the [] operator doesn't perform any checks1. You get a faster program, but you-the-programmer have to promise that the program will never go out of bounds.
The std::vector::at method does check and will throw an exception, but by using at you've opted-in for a slightly slower program.
1Doesn't require any checks is a better way to word this. In this case the vector implementation in the debug version of the MicroSoft standard library implementation does check by default and the "Debug Assertion Failed!" message is the direct result. Debug builds are optimized to make debugging easier and tend to be slow. This checking doesn't happen in the release library because the release builds are optimized for performance.
std::system_error handles exception with associated error code. Is it possible using common catch block to get std::system_error exception message and it's code? Like this
try{
// code generating exception
} catch (const std::exception& ex){ // catch all std::exception based exceptions
logger.log() << ex.what(); // get message and error code
// if exception type is system_error
}
Is the only way is to catch directly std::system_error type and get its code before base exception type catching? What is the best approach to use std::system_error widely?
What is the best approach to use std::system_error widely?
The best approach in my opinion, is to catch the exception directly.
catch (const std::system_error& e) {
std::cout << e.what() << '\n';
std::cout << e.code() << '\n';
} catch (const std::exception& e) {
std::cout << e.what() << '\n';
}
Is the only way is to catch directly std::system_error type and get its code before base exception type catching?
It's technically not the only way. It's the obvious and idiomatic way. You can use dynamic_cast.
catch (const std::exception& e) {
std::cout << e.what() << '\n';
auto se = dynamic_cast<const std::system_error*>(&e);
if(se != nullptr)
std::cout << se->code() << '\n';
}
But you mention in the comment that you prefer not to use dynamic_cast. It's possible to avoid that too, but not in any way that has any advantages.
Note that even if you can do things in non obvious ways, it doesn't mean that you should.
I use marmalade sdk and there is no support for structured exceptions handling. I need to catch any exception (null pointer, devision by zero or any else) and do some actions before app will crashed (send crash report). How can I do this in native c++ under gcc-arm compiller?
I need to catch any exception
To do so you can use the ellipsis syntax of catch:
try {
doStuff(); // May throw
}
// catch all exceptions derived from std::exception
catch(const std::exception& ex) {
std::cerr << "Caught exception: '" << ex.what() << "'" << std::endl;
}
catch(...) { // catch everything but unkown
}
Also ensure that your build system doesn't suppress exceptions and RTTI explicitly with the -fno-exceptions and -fno-rtti compiler flags.
I've already asked it here. I tried it with the flag enable-exceptions=1 in options. But it never worked for me. There was a thread on Marmalade regarding the exception handling and it was mentioned there that Marmalade doesn't support them and it was demanded by the community to include this.
The below given simple exception program is giving Unhandled Exception "Microsoft C++ exception: int at memory location 0x0012fe94..". I am getting this error immediately after the function excep() is returned.
Please can anyone tell why this error is coming here. Also it will be helpful if all the possible mistakes in this code were explained/analysed. I am learning to code better.
I am using Visual C++ 2005.
#include <iostream>
using namespace std;
int main ()
{
int excep(int);
throw excep(20);
return 0;
}
int excep(int e)
{
cout << "An exception occurred. Exception Nr. " << e << endl;
return 0;
}
If you try to learn exception throwing/handling your code contains an error.
function excep must handle object that was thrown not to be thrown itself.
your code must be rewritten as follows:
using namespace std;
int excep(int e)
{
cout << "An exception occurred. Exception Nr. " << e << endl;
return 0;
}
int main ()
{
int excep(int);
try
{ // <--------- Begin of try block. required part of the exception handling
throw 20;
}
catch (const int &errCode) // <------- we are catching only ints
{
excep(errCode); // Function that handles exception
}
return 0;
}
It is good design not to throw int variables, but type that inherites std::exception. But this is more advanced exception using knowledge
What did you expect to happen?
You call a function which prints out "An exception occurred", plus the other text, and then you throw the resulting value as an exception, which you never catch, so the program reports than an uncaught exception was thrown. Which is true, because that's exactly what you just did.
The entire point in exceptions is that when you throw an exception, it will propagate out through the program, until it is either handled, or it reaches the top level and terminates the program. You don't handle the exception, so it terminates the program.
If you want to handle an exception, you need to wrap the throwing code in a try block, followed by a catch, as in:
try {
throw excep(20);
}
catch (int ex) {
// do something about the exception
}
In the line
throw excep(20);
excep(20) is called first, whose return value is then thrown, i.e. you throw an integer. It is roughly equivalent to:
const int i = excep(20);
throw i;
To get you an idea how exception-snytax looks:
#include <iostream>
#include <stdexcept>
using namespace std;
int main ()
{
try {
// do something
throw std::runtime_error("test");
} catch (const std::exception &e) {
std::cout << "exception: " << e.what() << std::endl;
}
}
In practive: NEVER throw anything that is not derived from std::exception.
Proposed Readings:
Introductory book on C++ (search stackoverflow for this)
C++ FAQ on Exception Handling
"Exceptional C++" (for advanced C++ users)
This question already has answers here:
C++ get description of an exception caught in catch(...) block
(6 answers)
Closed 6 years ago.
If I want to write useful info to a file whenever i caught a catch-all exception, how to do it?
try
{
//call dll from other company
}
catch(...)
{
//how to write info to file here???????
}
You can't get any information out of the ... catch block. That is why code usually handles exceptions like this:
try
{
// do stuff that may throw or fail
}
catch(const std::runtime_error& re)
{
// speciffic handling for runtime_error
std::cerr << "Runtime error: " << re.what() << std::endl;
}
catch(const std::exception& ex)
{
// speciffic handling for all exceptions extending std::exception, except
// std::runtime_error which is handled explicitly
std::cerr << "Error occurred: " << ex.what() << std::endl;
}
catch(...)
{
// catch any other errors (that we have no information about)
std::cerr << "Unknown failure occurred. Possible memory corruption" << std::endl;
}
A caught exception is accessible by the function std::current_exception(), which is defined in <exception>. This was introduced in C++11.
std::exception_ptr current_exception();
However, std::exception_ptr is an implementation-defined type, so you can't get to the details anyway. typeid(current_exception()).name() tells you exception_ptr, not the contained exception. So about the only thing you can do with it is std::rethrow_exception(). (This functions seems to be there to standardize catch-pass-and-rethrow across threads.)
There's no way to know anything about the specific exception in a catch-all handler. It's best if you can catch on a base class exception, such as std::exception, if at all possible.
You can't get any details. The whole point of catch(...) is to have such "I don't know what can happen, so catch whatever is thrown". You usually place catch(...) after catch'es for known exception types.
I think he wants to make it log that an error occurred, but doesn't specifically need the exact error (he would write his own error text in that case).
The link DumbCoder posted above has at tutorial that will help you get what you're trying to achieve.