I know that the general method for using the try catch duo is something like this:
try
{
//your code
}
catch(...)
{
//any error goes here
}
Is there a way by which catch() catches the error code without giving any input... i.e if I didn't throw an exception but the c compiler did, then the error code can be anything. I just need to catch whatever the error code is and be notified that's all.
Apparently, you're trying to catch errors from functions that don't throw exceptions but return numerical error codes. That's impossible. The closest you can get is wrapping all your C functions in exception throwing code yourself:
FILE *safe_fopen(char const *path, char const *mode)
{
FILE *f = std::fopen(path, mode);
if (f == NULL)
throw std::runtime_error(std::strerror(errno));
return f;
}
It is not possible to throw an exception when a program derefences a null pointer or an invalid piece of memory, at least not in a portable manner; when that happens, behavior is simply undefined. There's no error code to check for, just a segfault on most OSs.
But please get your terminology straight. The compiler does not throw an exception, a function may do so, at run-time. The C compiler has very little to do with all this.
You don't have to catch everything. If you only want to handle a particular type of exception, only catch that exception:
try {
} catch (MyExceptionType ex) {
}
Related
I have a library I use that throws something, but I don't know how to identify what was being thrown.
Sample code to reproduce this:
int main()
{
char* memoryOutOfBounds;
unsigned __int64 bigNumber = -1;
try {
throw std::string("Test");
memoryOutOfBounds = new char[bigNumber];
}
catch (const std::bad_alloc& ex)
{
printf("Exception: %s\n", ex.what());
}
catch (...)
{
printf("Unknown.\n");
}
return 0;
}
The new char[bigNumber] will throw a std::bad_alloc, which is derived from std::exception and will enter the first branch. The other one, throw std::string will enter the second branch. How can I check the object that was thrown? I tried with a catch(void*) in the hopes to catch any object in memory, but that did not happen, so how can I find out what was thrown and from there debug what may have caused this?
catch (...) {}
means: Catch absolute everything that was thrown and drop it. This is only meant as a safeguard, so no exceptions fly out of the window and bring down the whole house. (Aka: Application Termination by Unhandled Exception")
There is no way to tell what was thrown in here.
But as you actually know that an std::string can be thrown, you can catch it in a
catch (const std::string& s) {}
block. You do need to know what (type) was thrown whenever you want to catch exceptions.
However, most libraries which add their own types for exceptions will have them inherit from std::exception. Therefore a
catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
block should get them.
If they do not inherit from std::exception and/or block the what() method, it is a stupid way to make the usage of their library extra difficult.
However, somewhere in the documentation of the library the exception throwing behaviour should be explained.
Edit : I think that Point 1. under "How should I design my exception classes" on the Boost Error Handling document is something every library developer should keep in mind. And hopefully the developers of your library did keep that principle in mind. ;-)
There really is no standard C++ way to query any information about the exception that is being thrown. Which is unfortunate, because the runtime has that information in order to match catch blocks. But there is just no access to that information in user code.
If it's purely for research purposes, like just finding out what the type is because the library you're using lacks documentation, you could use std::current_exception() to get a std::exception_ptr object that stores (or references) the thrown exception internally. This type is implementation-defined, but your debugger might happen to provide you with enough information.
#include <exception>
void foo()
{
try
{
function_that_throws();
}
catch(...)
{
std::exception_ptr p = std::current_exception();
// break here and inspect 'p' with a debugger
}
}
This stackoverflow post would be helpful-
C++ get description of an exception caught in catch(...) block
Since C++11 you can capture the current exception with a pointer:
std::exception_ptr p; // default initialization is to nullptr
try {
throw std::string("Test");
}
catch(...)
{
p = std::current_exception();
}
An exercise from C++ Primer asks
Why is it important that the what function [of exception classes] doesn’t throw?
Since there is no way to check my answer I was hoping to get an opinion. I thought possibly that it is an error (maybe terminate would've been called) to throw another exception during a catch clause (other than a rethrow throw;) while the current exception object is still being handled. It seems that is not the case though and it is completely okay to throw out of catch clauses:
#include <iostream>
using namespace std;
int main(){
try{
try{
throw exception();
} catch(exception err){ throw exception();}
} catch(exception err){ cout << "caught"} //compiles and runs fine, outputs "caught"
}
So program terminations are not a worry. It seems then, any problem that arises from what() throwing should, at the very least, be rectifiable by the user if they were so inclined.
Maybe then, the importance might be that while handling an error we do not want further unexpected errors to occur? Throws inside catch clauses are mainly intended for sending the exception object further up the call chain. A user may receive an error from deep in his program and does not want to worry that the error caught has to be associated with its own try block. Or maybe what() having its own throw may also lead to recursive effects (e.g. what() throws an exception, then we catch this exception and call what() but this then throws, and so on) meaning it might become impossible to handle any errors? How drastic can it be for what() to potentially throw?
I think there's nothing unclear - it's just as you described. If .what() method of an exception class throws an error, the whole catch effort was wasted:
try {
someDangerousOperation();
}
catch(std::exception e) {
// Ooops, instead of false,
//we get another exception totally unrelated to original error
someLogClassOrWhatever.save(e.what());
return false;
}
return true;
And Imagine the crazy code if you were expected to deal with what()'s exceptions:
try {
someDangerousOperation();
}
catch(std::exception e) {
// Not very fun
try {
someLogClassOrWhatever.save(e.what());
}
catch(...) {
alsoWhatHasFailedThatIsReallyGreat();
}
return false;
}
I think there's nothing more in that, probably the question is so simple it seems there must be some catch hiding in it. I think it's not the case.
std::exception::what() is noexcept. Consequently, if it throws, std::terminate is called. Yes, this is important.
Image a very curious coder with a slight tendency towards being a control freak (I know a couple of them myself), he really wants to know what is going wrong in his program and logs all errors with ex.what(). So he codes
try {
code();
}
catch(std::exception &e) {
std::cout<<e.what()
}
He is pretty pleased with the world in general and with himself in particular. But now it crosses his mind, that e.what() could throw an exception as well. So he is codes:
try{
try {
code();
}
catch(std::exception &e) {
std::cout<<e.what()
}
}
catch(std::exception &e) {
std::cout<<e.what()
}
A minute later he notices, that there is again an uncaught exception possible! Remember, he is a control freak, so he is going to write another try-catch block and than another and another
So you can bet any money, his project will be late - how could you do something like this to my friend? So please make sure e.what() doesn't throw:)
I guess it is the reason behind what being noexcept.
I'm getting this exception message in the IDE output log even though I have a code that catches it, if it happens.
Here's the code itself:
t_ptr obj_ptr;
try {
obj_ptr = _objects.at(file);
}
catch (std::out_of_range e) {
return nullptr;
}
return obj_ptr.get();
Is it supposed to happen? It's not like I'm using obj_ptr when std::map.at() fails.
"First-chance" exception means just that the debugger noticed that an exception has been thrown. That's not an error (and in facts the execution goes on), just an aid to the programmer that may be on the look for exceptions being incorrectly swallowed.
Learning "try & catch". What is wrong with the following code?
Thanks for the advice.
Error in execution:
terminate called without an active exception
Aborted
The code:
#include <stdio.h>
int main()
{
int a = 3;
try
{
if (a < 5)
throw;
}
catch (...)
{
printf ("captured\n");
}
return 0;
}
Your throw; statement tries to rethrow a current exception but there probably isn't one. You need something like
throw some_exception_object();
Inside of a try block, you have to specify what to throw. The only place you can use throw by itself is inside of a catch block to re-throw the current exception. If you call throw by itself without a current exception being active, you will kill your app, as you have already discovered.
Try this:
#include <stdio.h>
int main()
{
int a = 3;
try
{
if (a < 5)
throw 1; // throws an int
}
catch (...)
{
printf ("captured\n");
}
return 0;
}
You can throw anything you want, as long as you throw something.
There are four things, two major and two minor. One thing at a time...
1. Rethrow usage w/o active exception
A throw; statement is used to re-throw an exception that is currently caught. For example:
try {
do_something();
} catch (const std::exception &) {
throw; // This statement re-throws an exception that was caught in this "catch" block.
}
In your case, you are using throw; without catching any exceptions (in order words — it does not appear inside catch block directly or indirectly), thus your program is terminated. When there is a need to throw and not to re-throw an exception, like in your case, you must specify an exception object to be thrown. For example:
throw std::runtime_error("Something bad happened");
2. catch-all clause which does not re-throw a caught exception
Your catch-all clause (catch (...)) is perfectly legal C++. However, it does not re-throw caught exception. Even though it is a legal C++ code, such a usage is a taboo. C and C++ runtime is usually using special types of exceptions to implement certain functionality. For example, NPTL is using exceptions to implement a thread cancellation. If you catch that exception using catch (...), a thread won't be cancelled and you are going to have a bad time. Generally, you have to catch exceptions by their types. In almost all cases, exceptions are inherited from std::exception, and so you have to write catch (const std::exception &) or, if you expect to catch an exact type, - catch(const TypeYouExpect &). If you must, however, use catch-all, remember to re-throw. For example:
try {
do_something();
} catch (...) {
throw; // DO NOT FORGET TO RE-THROW.
}
3. Header naming...
You are including C header whereas C++ provides its own headers for standard C features. So, header:
#include <stdio.h>
.. should be:
#include <cstdio>
C++ specific C functions get special treatment. For example, they become available in std namespace. So that you can use std::open() instead of just open() or ::open(). No big deal, but is highly recommended way to go.
4. Return from main.
Unlike C, C++'s main() function is very special. It allows you not to have return 0;. This is a default behavior. So, unless you really need to return some value, you may save yourself some time by not typing return 0;. Remember, however, that main is the only function like that, and that everywhere else you must explicitly return something unless a function is marked void.
Hope it helps. Good Luck!
You need to actually throw some object. Even something as simple as
throw "error";
will catch the error like you want it to.
see it in action here
The statement to throw an exception is:
throw <expression>;
This statement:
throw;
is also called the re-throw statement and is use to re-throw an existing exception that has been caught. It is typically used in a catch block, for example, you look at the exception and decide if you can continue, retry or abort. In case you decide to abort, you re-throw the exception so that somebody else down the call stack will catch it and handle this error.
For example:
// getResult() calls can fail with a deadlock exception
// This method will retry up to 3 times before failing
Result getResultWithRetry()
{
int nbTry = 3;
for(;;) {
try {
return getResult();
} catch (DeadLockException& e) {
if (nbTry == 0) {
throw; // re-throw the deadlock exception
}
}
--nbTry;
}
}
I'm using the GLUTesselator and every once in a while EndContour() fails so I did this:
try
{
PolygonTesselator.End_Contour();
}
catch (int e)
{
renderShape = false;
return;
}
Why would it still crash, it should perform the catch code right?
How could I fix this?
Thanks
Does PolygonTesselator.End_Contour(); crash or throws it an exception?
Note that a real "crash" (segfault, illegal instruction etc.) does not throw an exception in the sense of C++.
In these cases, the CPU triggers an interrupt - this is also sometimes called exception, but has nothing to do with an C++ exception.
In C++ you are running on a real CPU - and not in a virtual machine like in Java where every memory violation results in language execption like NullPointerException or ArrayOutOfBoundsException.
In C/C++ a CPU exception / interrupt / trap is handled by the operating system and forwarded to the process as "signal". You can trap the signal but usually this does not help for crashes (SIGSEG, SIGILL, SIGFPU, etcc.).
You're getting SEH exception, or Structured Exception Handling. These exceptions are thrown by Windows under an entirely different system since SEH predates C++, and can't be caught by a standard C++ catch block (MSVC does however provide SEH catching).
Alternatively, if you're on Unix, the kernel doesn't use C++ exceptions either. It uses signals. I don't pretend to understand signals, since I don't develop for Unix, but I'm very sure they're not C++ exceptions.
You've violated a hardware rule that you can't de-reference a NULL pointer. You'll get an OS-level error, by exception or signal. You can't catch these things in a C++ catch block just like that.
Edit: If you're using MSVC on Windows and have a recent compiler, you CAN enable /EHa, which allows you to catch Structured Exceptions as well as C++ exceptions. I wrote this code that functions as shown:
int main() {
std::string string = "lolcakes";
try {
Something s;
int i, j;
i = 0; j = 1;
std::string input;
std::cin >> input;
if (input == "Structured")
int x = j / i;
else
throw std::runtime_error("Amagad hai!");
}
catch(std::runtime_error& error) {
std::cout << "Caught a C++ exception!" << std::endl;
}
catch(...) {
std::cout << "Caught a structured exception!" << std::endl;
}
return main();
}
Structured Exceptions include Access Violations, your particular error.
Two things :
If you are under VC 6 or more recent, use __try{}__except(EXCEPTION_EXECUTE_HANDLER){} instead. It will catch the SE. try/catch only catches C++ exceptions
I've had a hard time with GLU, so I can tell you this : if you can set the normal, SET IT. But otherwise, it's true that it's quite solid.
Since all you want to do when the exception arrives is set 'renderShape' to false I'd recomment the following code:
try
{
PolygonTesselator.End_Contour();
}
catch (...) // takes any type of exception
{
renderShape = false;
return;
}
That said of course if you really can't fix the source to the exception itself!!
Why would it still crash, it should
perform the catch code right? How
could I fix this?
Most likely because you are not actually catching what is being thrown. Are you sure that PolygonTesselator.End_Contour(); throws an int?
If your program fails with the message error reading from location 0x000000000, then it is not failing because of an exception, but because of a segfault. You can use the segvcatch utility to convert segfaults into catchable exceptions. Check out their examples.
As mentioned, this is an SEH Exception.
If you are using Visual Studio, you can configure your project to catch SEH exceptions in your try/catch block.
Project Properties > C/C++ > Code
Generation > Enable C++ Exceptions >
Yes with SEH Exceptions