I write some code guarded with exception handling...
simplified code look like this...
int main(int argc, char* argv[]){
try{
// code that might be throw runtime exception
// .....
// .....
}
catch(...){
}
return 0;
}
but when I ran the code, how come the code throw uncaught runtime
exception ?
I think the catch(...) block should catch all runtime exception ...
Or am I wrong ?
Thanks in advance
Not sure what you mean by "runtime exception". "runtime_error"s
(range_error etc) will be caught by catch(...). If you are talking
about floating point exceptions etc, they are asyncronous events and
hence are not handelled by C++ exception handling mechanism.
Posting the actual code might help.
> Thanks in advance
So, there's no way in C++ I can handle any runtime exception ?
Anyway, I'm coming from Java environment, and all exception
inherited from Exception class, so I can caught all runtime
exception. the point is, how can I prevent my code to "explode",
caused by uncaught exception.
In C++, if you have an integer divide by zero, say, you have a bug that
should be fixed.
There is no guarantee of exceptions for bug manifestations.
Neither is there such a guarantee in Java, but in Java you have a better
chance of suppressing the most common _immediate_ effects of bugs, the
Ostrich policy of "what I don't see doesn't exist", until the bugs have
multiplied & migrated to the point where the code can't be rescued.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
#ifndef SIG_EXCEPT_H
#define SIG_EXCEPT_H
/*******************************************************************************
File name : sigexception.h
Programmer : Yuval Lifshitz
Date : 03-sep-2003
Description : Try/Catch mechanism for OS signals.
Usage example:
TRY {
// write code here
}
CATCH {
// write code here
ex.WriteMsg();
cout << "signal number = " << ex.getSignal() << endl;
}
Notes: (1) This mechanism is NOT thread safe.
(2) The CATCH macro must follow immediatly after the
closing brackets of the TRY macro
(3) inside the CATCH block there exists a local variable
named ex holding the thrown signal data.
Change log : 23-sep-2004 make gcc compatible
add thread index hashing
*******************************************************************************/
// include files
#include <stack>
#include <iostream>
#include <pthread.h>
#include <signal.h>
#include <setjmp.h>
// signal description list - used at the psignal function
extern const char *const sys_siglist[];
// jump function type
extern "C" {
typedef void (*jump_func_t)(int);
}
// main class definition
class TryCatchAsync
{
public:
// const and enum
enum {MAX_THREAD_NUM = 100};
//---------------------------
// internal class/type definitions
//---------------------------
//---------------------------------------------------------------
// Class Name : sigjmp_container
// Description : Container to encapsulate the sigjmp_buf type.
// This is done for the conviniece of allocation,
// since the original type is an array of integers.
//----------------------------------------------------------------
class sigjmp_container {
private:
sigjmp_buf m_sigbuf;
public:
sigjmp_container() {}
~sigjmp_container() {}
operator sigjmp_buf * ()
{
return &m_sigbuf;
}
sigjmp_buf * get_buf()
{
return &m_sigbuf;
}
};
//-----------------------------------------------
// Class Name : Exception
// Description : The exception thrown by the try
//-----------------------------------------------
class Exception {
public:
Exception(int sig) : m_sig(sig) {}
int getSignal() const
{
return m_sig;
}
void WriteMsg() const
{
psignal(m_sig, "signal thrown");
}
private:
int m_sig;
};
// jump adresses stack type
typedef std::stack<sigjmp_container> jump_stack_t;
// the constructor is used to generate the array of jump functions
// the object should be instanciated only once - but has no effect
// if instanciated more then once, since the relevant execution
// is done in compile time
// constructor
TryCatchAsync();
// destructor
~TryCatchAsync() {}
// static member functions
static void SigMaskAdd(int sig);
static void Push(sigjmp_container &curr_addr);
static void Throw();
static int GetThreadIndex();
// member functions
template <int func_id>
static void Jump(int sig)
{
pthread_t pt = GetThreadIndex();
m_sig[pt] = sig;
siglongjmp(*(sigjmp_buf *)m_addr[pt].top().get_buf(), 1);
}
private:
// data members
static int m_sig[MAX_THREAD_NUM];
static jump_stack_t m_addr[MAX_THREAD_NUM];
static jump_func_t m_jump_func[MAX_THREAD_NUM];
};
//-----------------------------------------------
// Class Name : JUMP_FUNC_GENERATOR
// Description : a template struct that instanciate
// an array of different "Jump" functions.
// Note: this is done in a "generative programming"
// method in compile time.
//-----------------------------------------------
template <int N>
struct JUMP_FUNC_GENERATOR
{
JUMP_FUNC_GENERATOR(jump_func_t *jump_func_arr)
{
jump_func_arr[N-1] = TryCatchAsync::Jump<N-1>;
JUMP_FUNC_GENERATOR<N-1> tmp_creator(jump_func_arr);
tmp_creator = tmp_creator; // to avoid "unusead variable" warning
}
};
// termination condition for the generative process
template <>
struct JUMP_FUNC_GENERATOR<0>
{
JUMP_FUNC_GENERATOR(jump_func_t *jump_func_arr)
{
jump_func_arr[0] = TryCatchAsync::Jump<0>;
}
};
//------------------
// macro definitions
//------------------
#define SIG_INIT \
TryCatchAsync::SigMaskAdd(SIGFPE); \
TryCatchAsync::SigMaskAdd(SIGSEGV); \
TryCatchAsync::SigMaskAdd(SIGILL); \
TryCatchAsync::SigMaskAdd(SIGBUS);
// note: new signals should be added in the SIG_INIT macro
#define TRY SIG_INIT try { TryCatchAsync::sigjmp_container curr_addr;\
if (sigsetjmp(*(sigjmp_buf *)curr_addr, 1) == 0) { \
TryCatchAsync::Push(curr_addr); \
} \
else { \
TryCatchAsync::Throw(); \
}
#define CATCH } catch(TryCatchAsync::Exception &ex)
#endif // RSEXCEPT_H