19

I have found the automatic break-on-exception feature of Visual C++ 2010 to be very helpful in the past and today I was looking through the options in this dialog and discovered that one of the exception types is "void". What does this mean? If I select this, will I break on any exception that is thrown in the code? If not, what kind of a throw statement would trigger a breakpoint of this type?

Visual Studio Exceptions Dialog

I suppose a more general follow-up question is where can I find documentation on this dialog and all its options?

3
  • 3
    My first bet would have been: it's meant as a proxy for any type not derived from any of the other exceptions (including throw 5;). A short test reveals: that's not the case - looking forward to the answer...
    – MFH
    Commented Jan 25, 2013 at 19:27
  • Just curious: did you manage to get it to catch a "void" exception in the debugger?
    – doug65536
    Commented Jan 28, 2013 at 21:52
  • @doug65536 Well, interestingly, if I used a void* I was about to get it to work, but that doesn't seem like the use it was intended for.
    – Joe Bane
    Commented Jan 28, 2013 at 21:53

3 Answers 3

12
+50

Regarding on how does it work (as MSalters mentioned) this is just about incorrect naming.

Actually it shall be named void*, of course.

But why does it work for int*, const char* etc (actually any pointer type, including pointer to user defined types)?

Well, I can suppose this is related to very interesting C++ exception handling issue - catch(void*) exception handler actually catches any (cv-compatible) pointer type exceptions!

Example:

try
{
   throw "Catch me if you can!";      
}
catch(void* e)
{
   // ...and I can!
   std::cout << "Gotcha!" << std::endl;
}

Here we throw char* (in Visual C++ char literals are char*, not const char*) and catch it by void*. And it will work!

The answer can be found in C++ Holy Standard:

§15.3 Handling an exception

15.3.3 A handler is a match for an exception object of type E if

...

the handler is of type cv1 T* cv2 and E is a pointer type that can be converted to the type of the handler by either or both of — a standard pointer conversion (4.10) not involving conversions to pointers to private or protected or ambiguous classes

...

And 4.10 says that standard pointer conversion includes conversion to void*:

4.10.2 A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”.

Note also that Visual Studio debugger works similar way, but not exactly this way. The difference is that it ignores cv-qualifiers. So void in Exceptions dialog actually means any [any cv] void*. Catch handlers will not ignore them:

try
{
   struct Throwee {};
   const Throwee* t = nullptr;
   throw t;      
}
catch(void* e)
{
   // Will be missed
   std::cout << "Gotcha!" << std::endl;
}
catch(const void* e)
{
   // Will be catched
   std::cout << "Gotcha const!" << std::endl;
}
1
  • Excellent. This is precisely what I was looking for. Thanks!
    – Joe Bane
    Commented Jan 29, 2013 at 19:28
4

I've found that it will break when throwing a void*, int* or char const*, but not int.

0

It may be that's the setting for catch (...). Either that propagated throw; statements.

2
  • Nope, that's not it. A simple test confirmed it was not the case for me.
    – Joe Bane
    Commented Jan 28, 2013 at 21:59
  • And a throw; outside of a catch block causes an unhandled exception which isn't caught by catch(...) since it's a structured exception.
    – Joe Bane
    Commented Jan 28, 2013 at 22:01

Not the answer you're looking for? Browse other questions tagged or ask your own question.