I wrote my error handler that throws exceptions instead of printing
error messages and calling abort(). I attach the relevant code in case
anyone wants to analyse it.
At any rate, my error handler does indeed throw exceptions, but is
there something I am not understanding about C/C++ or the GSL? I ask
because e.g. in the following code:
#include <iostream>
#include "error.h"
int main(int argc, char** argv){
using namespace std;
gsl_set_error_handler(&error_handling::errorHandler);
gsl_vector* thing = gsl_vector_alloc(10);
try{
gsl_vector_ptr(thing, 100);
}catch(...){
cout << "Exceptions work!" << endl; //Never gets here.
abort();
}
}
the exception isn't caught, and I end up with something that is worse
than the default GSL error handler, namely, also terminates abruptly
and gives even less information than the default. :-(
Why aren't my exceptions unwound back up to the code that throws them?
Thanks again,
- Jordi G. H.
// File with a few function definitions.
#include "include/error.h"
#include <string>
#include <sstream>
namespace error_handling{
void errorHandler(const char * reason, const char * file,
int line_int, int gsl_errno){
//This exception is so common that we will want more information
//when it happens.
std::stringstream converter;
std::string line;
converter << line_int;
converter >> line;
if(reason == "index out of range"){ //GSL gives this message.
throw indexOutOfRange(reason,file,line);
}
else{ //Other exceptions are more generic
switch(gsl_errno){
case -2:
throw noConvergence(reason,file,line); break;
case 1:
throw badDomain(reason,file,line); break;
case 2:
throw badRange(reason,file,line); break;
case 3:
throw badPointer(reason,file,line); break;
case 4:
throw badArgument(reason,file,line); break;
case 5:
throw failure(reason,file,line); break;
case 6:
throw failedFactorisation(reason,file,line); break;
case 7:
throw failedSanity(reason,file,line); break;
case 8:
throw outOfMemory(reason,file,line); break;
case 9:
throw badFunction(reason,file,line); break;
case 10:
throw runAway(reason,file,line); break;
case 11:
throw maxIterations(reason,file,line); break;
case 12:
throw divideByZero(reason,file,line); break;
case 13:
throw badTolerance(reason,file,line); break;
case 14:
throw aboveTolerance(reason,file,line); break;
case 15:
throw underflow(reason,file,line); break;
case 16:
throw overflow(reason,file,line); break;
case 17:
throw lossOfAccuracy(reason,file,line); break;
case 18:
throw roundOffError(reason,file,line); break;
case 19:
throw incomformantSizes(reason,file,line); break;
case 20:
throw matrixNotSquare(reason,file,line); break;
case 21:
throw singularityFound(reason,file,line); break;
case 22:
throw integralOrSeriesDivergent(reason,file,line); break;
case 23:
throw badHardware(reason,file,line); break;
case 24:
throw notImplemented(reason,file,line); break;
case 25:
throw cacheLimitExceeded(reason,file,line); break;
case 26:
throw tableLimitExceeded(reason,file,line); break;
case 27:
throw iterationNotProgressing(reason,file,line); break;
case 28:
throw jacobiansNotImprovingSolution(reason,file,line); break;
case 29:
cannotReachToleranceInF(reason,file,line); break;
case 30:
throw cannotReachToleranceInX(reason,file,line); break;
case 31:
throw cannotReachToleranceInGradient(reason,file,line); break;
case 32:
throw endOfFile(reason,file,line); break;
default: //Corresponds to GSL_ERRNO=-1.
throw error(reason,file,line);
}
}
} //ends void handler(const char*, const char*, int, int);
} //Ends the error_handling namespace.
//Throw exceptions instead of using GSL error handler function which
//prefers to call abort().
//Remember to put `gsl_set_error_handler(&errorHandler);' in the
//main() loops when including this header file; otherwise it's
//useless!
#ifndef __ERROR_H__
#define __ERROR_H__
#include <gsl/gsl_errno.h>
#include <string>
namespace error_handling{
//Structs to be thrown as exceptions
using std::string;
class error{ //generic error and base struct.
public:
std::string reason, file, line;
error(){};
error(string r, string f, string l) :
reason(r), file(f), line(l) {};
};
//GSL_FAILURE = -1,
struct noConvergence ;
//GSL_CONTINUE = -2, /* iteration has not converged */
struct badDomain ;
//GSL_EDOM = 1, /* input domain error, e.g sqrt(-1) */
struct badRange ;
//GSL_ERANGE = 2, /* output range error, e.g. exp(1e100) */
struct badPointer ;
//GSL_EFAULT = 3, /* invalid pointer */
struct badArgument ;
//GSL_EINVAL = 4, /* invalid argument supplied by user */
struct failure ;
//GSL_EFAILED = 5, /* generic failure */
struct failedFactorisation ;
//GSL_EFACTOR = 6, /* factorization failed */
struct failedSanity ;
//GSL_ESANITY = 7, /* sanity check failed - shouldn't happen */
struct outOfMemory ;
//GSL_ENOMEM = 8, /* malloc failed */
struct badFunction ;
//GSL_EBADFUNC = 9, /* problem with user-supplied function */
struct runAway ;
//GSL_ERUNAWAY = 10, /* iterative process is out of control */
struct maxIterations ;
//GSL_EMAXITER = 11, /* exceeded max number of iterations */
struct divideByZero ;
//GSL_EZERODIV = 12, /* tried to divide by zero */
struct badTolerance ;
//GSL_EBADTOL = 13, /* user specified an invalid tolerance */
struct aboveTolerance ;
//GSL_ETOL = 14, /* failed to reach the specified tolerance */
struct underflow ;
//GSL_EUNDRFLW = 15, /* underflow */
struct overflow ;
//GSL_EOVRFLW = 16, /* overflow */
struct lossOfAccuracy ;
//GSL_ELOSS = 17, /* loss of accuracy */
struct roundOffError ;
//GSL_EROUND = 18, /* failed because of roundoff error */
struct incomformantSizes ;
//GSL_EBADLEN = 19, /* matrix, vector lengths are not conformant */
struct matrixNotSquare ;
//GSL_ENOTSQR = 20, /* matrix not square */
struct singularityFound ;
//GSL_ESING = 21, /* apparent singularity detected */
struct integralOrSeriesDivergent ;
//GSL_EDIVERGE = 22, /* integral or series is divergent */
struct badHardware ;
//GSL_EUNSUP = 23, /* requested feature is not supported by the hardware */
struct notImplemented ;
//GSL_EUNIMPL = 24, /* requested feature not (yet) implemented */
struct cacheLimitExceeded ;
//GSL_ECACHE = 25, /* cache limit exceeded */
struct tableLimitExceeded ;
//GSL_ETABLE = 26, /* table limit exceeded */
struct iterationNotProgressing ;
//GSL_ENOPROG = 27, /* iteration is not making progress towards solution */
struct jacobiansNotImprovingSolution ;
//GSL_ENOPROGJ = 28, /* jacobian evaluations are not improving the solution */
struct cannotReachToleranceInF ;
//GSL_ETOLF = 29, /* cannot reach the specified tolerance in F */
struct cannotReachToleranceInX ;
//GSL_ETOLX = 30, /* cannot reach the specified tolerance in X */
struct cannotReachToleranceInGradient ;
//GSL_ETOLG = 31, /* cannot reach the specified tolerance in gradient */
struct endOfFile ;
//GSL_EOF = 32 /* end of file */
//Custom error handler to be used for GSL. Throw exceptions instead of
//calling abort().
void errorHandler(const char * reason, const char * file,
int line, int gsl_errno);
}
//A few more details about the structs we're throwing as exceptions.
namespace error_handling{
using std::string;
struct noConvergence : public error {
noConvergence() {};
noConvergence(string r, string f, string l) :
error(r,f,l) {};
};
struct badDomain : public error {
badDomain() {};
badDomain(string r, string f, string l) :
error(r,f,l) {};
};
struct badRange : public error {
badRange() {};
badRange(string r, string f, string l) :
error(r,f,l) {};
};
struct badPointer : public error {
badPointer() {};
badPointer(string r, string f, string l) :
error(r,f,l) {};
};
struct badArgument : public error {
badArgument() {};
badArgument(string r, string f, string l) :
error(r,f,l) {};
};
struct failure : public error {
failure() {};
failure(string r, string f, string l) :
error(r,f,l) {};
};
struct failedFactorisation : public error {
failedFactorisation() {};
failedFactorisation(string r, string f, string l) :
error(r,f,l) {};
};
struct failedSanity : public error {
failedSanity() {};
failedSanity(string r, string f, string l) :
error(r,f,l) {};
};
struct outOfMemory : public error {
outOfMemory() {};
outOfMemory(string r, string f, string l) :
error(r,f,l) {};
};
struct badFunction : public error {
badFunction() {};
badFunction(string r, string f, string l) :
error(r,f,l) {};
};
struct runAway : public error {
runAway() {};
runAway(string r, string f, string l) :
error(r,f,l) {};
};
struct maxIterations : public error {
maxIterations() {};
maxIterations(string r, string f, string l) :
error(r,f,l) {};
};
struct divideByZero : public error {
divideByZero() {};
divideByZero(string r, string f, string l) :
error(r,f,l) {};
};
struct badTolerance : public error {
badTolerance() {};
badTolerance(string r, string f, string l) :
error(r,f,l) {};
};
struct aboveTolerance : public error {
aboveTolerance() {};
aboveTolerance(string r, string f, string l) :
error(r,f,l) {};
};
struct underflow : public error {
underflow() {};
underflow(string r, string f, string l) :
error(r,f,l) {};
};
struct overflow : public error {
overflow() {};
overflow(string r, string f, string l) :
error(r,f,l) {};
};
struct lossOfAccuracy : public error {
lossOfAccuracy() {};
lossOfAccuracy(string r, string f, string l) :
error(r,f,l) {};
};
struct roundOffError : public error {
roundOffError() {};
roundOffError(string r, string f, string l) :
error(r,f,l) {};
};
struct incomformantSizes : public error {
incomformantSizes() {};
incomformantSizes(string r, string f, string l) :
error(r,f,l) {};
};
struct matrixNotSquare : public error {
matrixNotSquare() {};
matrixNotSquare(string r, string f, string l) :
error(r,f,l) {};
};
struct singularityFound : public error {
singularityFound() {};
singularityFound(string r, string f, string l) :
error(r,f,l) {};
};
struct integralOrSeriesDivergent : public error {
integralOrSeriesDivergent() {};
integralOrSeriesDivergent(string r, string f, string l) :
error(r,f,l) {};
};
struct badHardware : public error {
badHardware() {};
badHardware(string r, string f, string l) :
error(r,f,l) {};
};
struct notImplemented : public error {
notImplemented() {};
notImplemented(string r, string f, string l) :
error(r,f,l) {};
};
struct cacheLimitExceeded : public error {
cacheLimitExceeded() {};
cacheLimitExceeded(string r, string f, string l) :
error(r,f,l) {};
};
struct tableLimitExceeded : public error {
tableLimitExceeded() {};
tableLimitExceeded(string r, string f, string l) :
error(r,f,l) {};
};
struct iterationNotProgressing : public error {
iterationNotProgressing() {};
iterationNotProgressing(string r, string f, string l) :
error(r,f,l) {};
};
struct jacobiansNotImprovingSolution : public error {
jacobiansNotImprovingSolution() {};
jacobiansNotImprovingSolution(string r, string f, string l) :
error(r,f,l) {};
};
struct cannotReachToleranceInF : public error {
cannotReachToleranceInF() {};
cannotReachToleranceInF(string r, string f, string l) :
error(r,f,l) {};
};
struct cannotReachToleranceInX : public error {
cannotReachToleranceInX() {};
cannotReachToleranceInX(string r, string f, string l) :
error(r,f,l) {};
};
struct cannotReachToleranceInGradient : public error {
cannotReachToleranceInGradient() {};
cannotReachToleranceInGradient(string r, string f, string l) :
error(r,f,l) {};
};
struct endOfFile : public error {
endOfFile() {};
endOfFile(string r, string f, string l) :
error(r,f,l) {};
};
struct indexOutOfRange : public badArgument{
size_t i,j,m,n;
indexOutOfRange() {};
indexOutOfRange(string r, string f, string l) :
badArgument(r,f,l) {};
};
}
#endif //__ERROR_H__
_______________________________________________
Help-gsl mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-gsl