Joshua Fox
Joshua Fox

Reputation: 19655

How to catch divide-by-zero error in Visual Studio 2008 C++?

How can I catch a divide-by-zero error (and not other errors; and to be able to access exception information) in Visual Studio 2008 C++?

I tried this:

try {
  int j=0;
  int i= 1/j;//actually, we call a DLL here, which has divide-by-zero
} catch(std::exception& e){
  printf("%s %s\n", e.what()); 
}  catch(...){
  printf("generic exception");
}

But this goes to the generic ... catch block. I understand that the MS-specific __try may be useful here, but I'd prefer standard C++, and in any case I have destructors which prevent the use of __try.

CLARIFICATION: The code above is simplified for discussion purposes. Actually, the divide-by-zero is a bug which occurs deep in a third-party DLL for which I do not have the source code. The error depends on the parameter (a handle to a complex structure) which I pass to the library, but not in any obvious way. So, I want to be able to recover gracefully.

Upvotes: 7

Views: 13580

Answers (9)

Oleksandr Filipenko
Oleksandr Filipenko

Reputation: 31

You can use try-except Statement. But, don't forget that you need to set it for each thread.

Upvotes: 0

Volodymyr Frytskyy
Volodymyr Frytskyy

Reputation: 1283

To catch divide by zero exceptions in Visual C++ try->catch (...) just enable /EHa option in project settings. See Project Properties -> C/C++ -> Code Generation -> Modify the Enable C++ Exceptions to "Yes With SEH Exceptions". That's it!

See details here: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx

Upvotes: 9

Bill
Bill

Reputation: 14685

Try the following code:

try
{ 
  const int j=0;
  if (j == 0) { throw std::exception("j was 0"); } 
  const int i= 1/j;    
}
catch(std::exception& e)
{ 
  printf("%s %s\n", e.what());  
}
catch(...)
{ 
  printf("generic exception"); 
}

Of course, if you're OK doing this without exceptions, you could do:

const int j = 0;
if (j == 0)
{
  /* do something about the bad pre-condition here */
}
else
{
  const int i = 1 / j;
}

Edit in response to clarification: you'll have to figure out what input it is that you're handing the third party that causes them to divide by zero before-hand, and handle that before ever calling their function.

Upvotes: 1

Georg Fritzsche
Georg Fritzsche

Reputation: 98984

A good approach would be to use safe object oriented wrappers like SafeInt. It also seems to be integrated in Visual Studio 2010.

update:
If the division-by-zero happens in third party code your only option is SEH or something equivalent as answered by Seb Rose

Upvotes: 1

Len Holgate
Len Holgate

Reputation: 21616

Assuming that you can't simply fix the cause of the exception generating code (perhaps because you don't have the source code to that particular library and perhaps because you can't adjust the input params before they cause a problem).

You have to jump through some hoops to make this work as you'd like but it can be done.

First you need to install a Structured Exception Handling translation function by calling _set_se_translator() (see here) then you can examine the code that you're passed when an SEH exception occurs and throw an appropriate C++ exception.

void CSEHException::Translator::trans_func(
    unsigned int code, 
    EXCEPTION_POINTERS *pPointers)
{
   switch (code)
   {
       case FLT_DIVIDE_BY_ZERO : 
          throw CMyFunkyDivideByZeroException(code, pPointers);
       break;
   }

   // general C++ SEH exception for things we don't need to handle separately....
   throw CSEHException(code, pPointers);
}

Then you can simply catch your CMyFunkyDivideByZeroException() in C++ in the normal way.

Note that you need to install your exception translation function on every thread that you want exceptions translated.

Upvotes: 9

Yuval Adam
Yuval Adam

Reputation: 165242

C++ does not handle divide-by-zero as an exception, per-se.

Quoting Stroustrup:

"low-level events, such as arithmetic overflows and divide by zero, are assumed to be handled by a dedicated lower-level mechanism rather than by exceptions. This enables C++ to match the behaviour of other languages when it comes to arithmetic. It also avoids the problems that occur on heavily pipelined architectures where events such as divide by zero are asynchronous."

"The Design and Evolution of C++" (Addison Wesley, 1994)

In any case, exceptions are never a replacement for proper precondition handling.

Upvotes: 9

Seb Rose
Seb Rose

Reputation: 3666

You can either use structured exception handling (using __try etc.) or you can install a structured exception handler translator: _set_se_translator

Both of these are operating system specific.

Upvotes: 7

Naveen
Naveen

Reputation: 73443

You can not do that using standard C++ as it is not standard C++ exception. It's a structured exception. For the standard C++ exception somebody has to do a throw exception; from the code.

Upvotes: 3

Daniel A. White
Daniel A. White

Reputation: 190945

Why not check for this before? The performance will be trivial for a simple j == 0 compared to context-switching for exception handling.

Upvotes: 2

Related Questions