Click here to Skip to main content
15,881,859 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi everyone,

STL C++ has a way of dealing with unexpected exceptions[^] that I would like to mimic. It's a very interesting feature that I would like to know how to implement.

The question is: how the hell do they do that? I checked the source code and it contains nothing but forward declarations, so I assume the implementation is compiled in the .dll

Anybody?

Regards
Posted
Updated 7-Jun-12 11:34am
v3

This is implemented by the compiler.

It is part of the C++ standard.

It is not implemented in the current Microsoft compilers:

http://msdn.microsoft.com/en-us/library/awbt5tew(v=vs.100).aspx[^]

But looks like they will implement it soon:

http://msdn.microsoft.com/en-us/library/awbt5tew(v=vs.110).aspx[^]

There is no way to do it except at the compiler level.
 
Share this answer
 
Comments
AndreFratelli 6-Jun-12 20:07pm    
Yes, VC doesn't even support exception specification (http://msdn.microsoft.com/en-us/library/sa28fef8.aspx), so it doesn't even make sense to talk about unexpected exceptions there.

Anyway, how would you suggest that to be done at the compiler level?
TRK3 6-Jun-12 20:38pm    
Imagine a try block around every function call with an explicit catch block for each specified exception type (which it just rethrows) and a generic catch block that invokes unexpected().

You can write that explicitly with the MS compilier -- so it's really just a simple matter of the compiler doing it for you implicitly (of course there is probably a more efficient way to do it -- but that gives you one idea of how it could be done).
AndreFratelli 6-Jun-12 21:04pm    
That would catch the exceptions not listed in the catch blocks, not the one not listed in the function declaration.

What I make of this: it can't be done. If VS doesn't support exception specification there is no way to know if an exception is not specified. Hell, none is.
TRK3 7-Jun-12 12:59pm    
Yes, but if you listed every exception that was in the function declaration -- then it would catch the exceptions that weren't listed.

So you, could do it manually (where you really cared to do it) -- or you could use modules from the LLVM to do it for you automatically. But then if you are going to do that, then just go ahead and use the Clang compiler that implements the spec. So, yeah, basically the way to do it is use a compiler that supports it.
AndreFratelli 7-Jun-12 13:44pm    
Yeah, it kind of loses its purpose...
Even if the compiler does support exception specifications you really don't want to use them.

The unexpected handler is global for a process, so there's absolutely nothing it can do that a top level exception handler can't. Nothing - not a dicky bird. In fact it's even worse than a top level exception handler because none of the destructors for objects currently in scope are guaranteed to be called. Even if you call exit() to bail out of your code destructors for automatic objects still aren't called. About the only sensible thing you can do is throw an exception that's (hopefully) of a type allowed by the specification and pray it reaches all the way to main or the thread function.

So you might as well write:
C++
int main()
try
{
    do_something();
}
catch( std::exception &e )
{
    std::cout << "Something went horribly wrong: " << e.what() << std::endl;
}
catch( ... )
{
    std::cout << "Something went horribly wrong, no idea what!" << std::endl;
}
as at least your code will clean up after itself and be in a deterministic state if you want to restart.
 
Share this answer
 
If you are using a compiler where unexpected handler is not implemented, you can provide a work-around on the application level. For this, it's enough to catch all exceptions on the top of the stack of each thread. It's important no to throw any exceptions in the exception handler in this case.

—SA
 
Share this answer
 
Comments
TRK3 6-Jun-12 20:33pm    
That's not really the point of unexpected is it?

Unexpected catches the exception at the point that it's first incorrectly propagated. It shows you the exact point where your specification doesn't match your implementation.

Catching something at the top level just tells you that you didn't catch it at a lower level -- it doesn't tell you if the thing that was thrown wasn't specified or not, just that you didn't catch it.
Aescleal 7-Jun-12 9:36am    
It doesn't show you anything - you know nothing about the context in which it's called. All you know is that a function tried throwing something that wasn't in the exception specification.
TRK3 7-Jun-12 13:09pm    
Really? Don't you at least have a stack trace at that point in a debugger?
Aescleal 7-Jun-12 17:28pm    
Why would you? Not sure about all compilers but the two I know about handle exceptions on a different stack to the one they get thrown on - it's a bit hard (but probably not impossible) to unwind the stack while it's in use.
TRK3 7-Jun-12 17:38pm    
Sure, you've already unwound the stack up to the point where propagating the exception becomes invalid -- so you don't have that information in the debugger (unless the compiler writer went to greate pains to give you a special expensive exception handling scheme that perserved it all) -- but you should have the information of the exact point where propagating the exception is invalid. And that's the point you want need to do something about it anyway (either handle the exception there, or specify that it can be thrown).

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900