Solved

Try / Catch

Posted on 2007-03-29
8
404 Views
Last Modified: 2008-01-09
Hi,

It's been a while that i've not program in C++. I remember how to use try / catch but I want to catch only exception that are Errors not every exception.

I explain. Some time my program quit with the message "memory cannot be read". I know where but not when. So I what to put a try catch around it. But if I put Catch (...) it always pass in the catch and I don't what it.

Did someone know what Exception I need to catch?

Thank you...

(Sorry for my poor english, It's not my first language)
0
Comment
Question by:lussier
  • 5
  • 2
8 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>Some time my program quit with the message "memory cannot be read". I
>>know where but not when. So I what to put a try catch around it. But if I
>>put  Catch (...) it always pass in the catch

That is because access violations are no C++ exceptions, but Windows SEH exceptions, which is a different mechanism. These are caught using

__try {

int* p = NULL;

int n = *p;

} __except(1) {

// catch "memory cannot be read"
}

Alternatively, you can specify a translator funciotn which translates SEH exceptions into C++ exceptions, see e.g. http://msdn2.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx ("_set_se_translator ") which works like

// crt_settrans.cpp
// compile with: /EHa
#include <stdio.h>
#include <windows.h>
#include <eh.h>

void SEFunc();
void trans_func( unsigned int, EXCEPTION_POINTERS* );

class SE_Exception
{
private:
    unsigned int nSE;
public:
    SE_Exception() {}
    SE_Exception( unsigned int n ) : nSE( n ) {}
    ~SE_Exception() {}
    unsigned int getSeNumber() { return nSE; }
};
int main( void )
{
    try
    {
        _set_se_translator( trans_func );
        SEFunc();
    }
    catch( SE_Exception e )
    {
        printf( "Caught a __try exception with SE_Exception.\n" );
    }
}
void SEFunc()
{
    __try
    {
        int x, y=0;
        x = 5 / y;
    }
    __finally
    {
        printf( "In finally\n" );
    }
}
void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
{
    printf( "In trans_func.\n" );
    throw SE_Exception();
}
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
See also http://msdn2.microsoft.com/en-us/library/de5awhsw.aspx ("Exception Handling Differences ") and http://msdn2.microsoft.com/en-us/library/5skw957f.aspx ("Mixing C (Structured) and C++ Exceptions") as well as http://msdn2.microsoft.com/en-us/library/ms680657.aspx ("Structured Exception Handling") for more general information.
0
 
LVL 39

Expert Comment

by:itsmeandnobodyelse
Comment Utility
>>>> but I want to catch only exception that are Errors not every exception.
Generally, an exception can only be thrown by one of the statements in the try block or one of the functions called there. I would say any of these exceptions are errors cause otherwise they should have been handled before. Access violation is when using a NULL pointer or a pointer not initialized or a pointer already deleted. If you don't catch the error your program will stop anyway. I don't think it is a good idea to *handle*  (ignore) such a case. I would prefer if the program crashes thus giving a chance to correct the error. Or take a memory exception. If you don't get a new allocation, your prog can't do anything. It even can't handle the error. Or a division by 0? How will yo handle it? It should have been handled already. Then, STL throws some exceptions but always the same issue: if it wasn't handled directly where the STL function was called but at a higher level in the call stack, you definitively have no chance to handle it reasonably. You only can ignore - what is bad - or report and exit ("We are very sorry but the program has a failuer and we have to exit. Please excuse for any inconvenience" what might be less good than let it crash cause you suppress the error information of the operation system by doing so.

>>>> not every exception.
If you called a function in try block where you know that it might throw an exception the case is different. You then could check explicitly for one or more special exceptions:

try
{
       functionThat MightThrowSpecialException();
}
catch (SpecialException1 se1)
{
      // handle exceptiom
}
catch (SpecialException2 se2)
{
      // handle exception 2
}
catch(...)
{
     // handle all other exceptions
}

As told, I wouldn't make the last cath(...).

Regards, Alex



0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>// handle all other exceptions

You probably don't mind providing a working example that shows how to catch a SEH exception such as an Access Violation using a C++ catch handler without a translator, do you?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:lussier
Comment Utility
Hi jkr,

First thank you for your response. I've try to use __try in my code but I get this error :

Cannot use __try in functions that require object unwinding

This is my code : (I don't know if it can help you.)

__try
{
// Call  POL_Police.@WinC.Gestion polices.Onglets.Version polices  { ++Call  Field: FIELDS/+Function, FrameControl, ParentControl, .Local }
    v->ObIn_POLFFD04.ChildControl31.Index29 = v->FrameControl33.Index29;
    v->ObIn_POLFFD04.ChildControl31.Index230 = v->ParentControl32.Index230;

    ObCallMgr::Call(p_fnc_data, &v->ObIn_POLFFD04, &v->ObOut_POLFFD04, OB_RTDI_POLFFD04);
    v->Environment0.xReturned_status11 = v->st_returned;
} __except(1)
{
                     //*********
      ObMessage::Box(MB_OK,"Error!!");
      //*********
}
0
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
Comment Utility
>>Cannot use __try in functions that require object unwinding

Yes, that's one slight inconventience with SEH handlers, but can easily be fixed by wrapping the '__try' frame around a function call like

__try
{
    GuardedFunction();
} __except(1)
{
                     //*********
      ObMessage::Box(MB_OK,"Error!!");
      //*********
}

void GuardedFunction()
{

// Call  POL_Police.@WinC.Gestion polices.Onglets.Version polices  { ++Call  Field: FIELDS/+Function, FrameControl, ParentControl, .Local }
    v->ObIn_POLFFD04.ChildControl31.Index29 = v->FrameControl33.Index29;
    v->ObIn_POLFFD04.ChildControl31.Index230 = v->ParentControl32.Index230;

    ObCallMgr::Call(p_fnc_data, &v->ObIn_POLFFD04, &v->ObOut_POLFFD04, OB_RTDI_POLFFD04);
    v->Environment0.xReturned_status11 = v->st_returned;
}

or just putting '__try' around the function that contains your above code.

Alternatively, try the approach using '_set_se_translator()' like

void trans_func( unsigned int, EXCEPTION_POINTERS* );

class SE_Exception
{
private:
    unsigned int nSE;
public:
    SE_Exception() {}
    SE_Exception( unsigned int n ) : nSE( n ) {}
    ~SE_Exception() {}
    unsigned int getSeNumber() { return nSE; }
};

void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )
{
    printf( "In trans_func.\n" );
    throw SE_Exception(pExp->ExceptionRecord.ExceptionCode);
}


//...

try
{

// Call  POL_Police.@WinC.Gestion polices.Onglets.Version polices  { ++Call  Field: FIELDS/+Function, FrameControl, ParentControl, .Local }
    v->ObIn_POLFFD04.ChildControl31.Index29 = v->FrameControl33.Index29;
    v->ObIn_POLFFD04.ChildControl31.Index230 = v->ParentControl32.Index230;

    ObCallMgr::Call(p_fnc_data, &v->ObIn_POLFFD04, &v->ObOut_POLFFD04, OB_RTDI_POLFFD04);
    v->Environment0.xReturned_status11 = v->st_returned;
}
catch( SE_Exception e )
{
    printf( "Caught a __try exception with SE_Exception.\n" );
}
0
 

Author Comment

by:lussier
Comment Utility
HI,

I've try the first option >>or just putting '__try' around the function that contains your above code.
didn't work.

I've try the second one but I have some question. (because I'm a C++ beginner)

1) why there's a division by 0 in this function
void SEFunc()
{
    __try
    {
        int x, y=0;
        x = 5 / y;
    }
    __finally
    {
        printf( "In finally\n" );
    }
}

2) I understant that I should put the try around my code but did I keep this code too
 try
    {
        _set_se_translator( trans_func );
        SEFunc();
    }
    catch( SE_Exception e )
    {
        printf( "Caught a __try exception with SE_Exception.\n" );
    }

Thank you again
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>1) why there's a division by 0 in this function

void SEFunc()
{
    __try
    {
        int x, y=0;
        x = 5 / y; // <--------- Here, 'y' is '0', making that 5 / 0
    }
}

>>2) I understant that I should put the try around my code but did I keep this
>>code too try

Now, that's a question on how the compiler generates the code that dispatches the exception to the correct catch handler. If that is done in a way that allows setting the translator func from within the code, that's fine, but I would not rely on it. Actually, I'd set the translator as early as possible.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now