0

I was reading thinking in c++ (exceptional handling).

I didn't understand following line

C++ exceptions cannot be used to handle asynchronous events because the exception and its handler are on the same call stack.

I tried searching over web but couldn't able to under stand this line.(specially call stack part) Can anyone help on it?

EDIT: what does same call stack means?

Suri
  • 3,287
  • 9
  • 45
  • 75
  • 2
    Never use exceptions to model program flow on the logical path. Just use them for, well exceptional error situations. – πάντα ῥεῖ Jul 29 '14 at 17:15
  • @πάνταῥεῖ: What has that to do with the question? – Deduplicator Jul 29 '14 at 17:18
  • 2
    @Deduplicator An asynchronous event isn't an exceptional error situation. May be the question asks about how exceptions per se can be exchanged between threads, but if so it is very unclear about this point. – πάντα ῥεῖ Jul 29 '14 at 17:21
  • Imagine what it would take to throw an exception asynchronously, say, in the middle of `std::swap(x,y)`. – n. m. could be an AI Jul 29 '14 at 17:24
  • 5
    Very little can be done safely in asynchronous code. A thread at least has its own stack and exception-handling (EH) context. Asynchronous code has no way to pass an exception up the call stack, since the function that was interrupted has no way of knowing that an exception is possible, or at what point in the function it occurred. – Brett Hale Jul 29 '14 at 17:26
  • possible duplicate of [How can I propagate exceptions between threads?](http://stackoverflow.com/questions/233127/how-can-i-propagate-exceptions-between-threads) – πάντα ῥεῖ Jul 29 '14 at 18:42

4 Answers4

2

Exceptions, when thrown, divert the current thread's execution path to the handling of that exception. There's no way to avoid this by, say, getting another thread to perform the exception handling. The stack is important here because the exception handling involves stack-unwinding which isn't conducive to asyncronouis event handling, or much else.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • Well, there actually are features to exchange/propagate exceptions from threads: [How can I propagate exceptions between threads?](http://stackoverflow.com/questions/233127/how-can-i-propagate-exceptions-between-threads) – πάντα ῥεῖ Jul 29 '14 at 17:36
  • @paul i understood your point that is stack unwinding needs to be done. but what does sharing same call stack means? – Suri Jul 29 '14 at 17:53
  • @Suri _'but what does sharing same call stack means?'_ It's simply fact, that different threads **never share the same call stack** by definition. There's **one** call stack per thread, and that's the **same** call stack, where all the exceptions thrown can be caught _per thread_. – πάντα ῥεῖ Jul 29 '14 at 18:35
  • @ πάντα ῥεῖ can i throw exception from handler as i will be knowing from where i paused by current program? – Suri Jul 30 '14 at 05:27
1

The problem is like so

try {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        // do some really long running operation here
        longFunctionToCalculate42();

        // oops, some critical error!
        throw std::runtime_error( "Something went wrong!" );
    });
} catch ( const std::exception& e ) {
    // this won't do what you think it does
    std::cerr << e.what() << std::endl;
}

The asynchronous block is executed separately from the call site, and the caller of that asynchronous function (the dispatched block) cannot catch the exception thrown from it.

aafulei
  • 2,085
  • 12
  • 27
Sam Miller
  • 23,808
  • 4
  • 67
  • 87
0

You actually can handle async events using exceptions. Weather or not you should is another matter. I'll only address that briefly: you usually shouldn't because there are more purpose-direct mechanisms to handle such things. Like passing messages between threads or raising some kind of event.

As to how you can accomplish this, what you have to do is catch the exception in the throw-ing thread, record the information somewhere, and have the other thread pick that up. Note that this really boils down fundamentally to passing messages between threads, with the additional complexity of stack unwinding and the like.

C++11 provides current_exception(), returning a exception_ptr, which provides the means to save the information about the exception somewhere the responding thread can pick it up. It is still up to you to build the code that actually retrieves and processes this exception_ptr up from wherever you saved it, and that's beyond the scope of this answer.

Note when thinking about this that, unless you need actual exceptions, doing this gains you nothing over simply passing messages between threads, and costs you the stack unwinding and semantic implications of throwing and catching exceptions.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
0

It means that asynchronous events do not follow the exception's model where "exception and its handler are on the same call stack". That is -

exceptions rely on the dynamic chain of function calls on the program s runtime stack (they have dynamic scope ), whereas asynchronous events must be handled by completely separate code that is not part of the normal program flow (typically, interrupt service routines or event loops)

Note "completely separate code", which means that you'd have to rely on some other mechanism to handle asynchronous events (if you really need so).

SChepurin
  • 1,814
  • 25
  • 17