1

This is the code:

#include <iostream>

void f() {
    throw 1;
    std::cout << "f(): should not be printed!!\n";
    std::cout << "f(): not should this!!\n";
}

int main(int, const char**) {
    f();
    std::cout << "main(): This not be printed!!\n";
    return 0;
}

When run as a console application, in debug mode and under the debugger there is no stack unwinding and the cout statements get printed?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Alex Net
  • 164
  • 12
  • try using namespace std , instead of all the std:: , i'm having hard time to understand what is the question? – Gilad Mar 02 '13 at 00:47
  • 3
    @Androidy: That's a bad idea, and has nothing to do with the question. – Mike Seymour Mar 02 '13 at 00:48
  • @MikeSeymour this was a comment, and why is this a bad idea ? – Gilad Mar 02 '13 at 00:49
  • 5
    @Androidy: Because polluting the global namespace with the contents of a huge namespace like `std` is a very good way to create name conflicts. It's a better idea to restrict the scope of any name as much as possible. But this argument is as off-topic as your comment, so let's end it here. – Mike Seymour Mar 02 '13 at 00:54
  • isn't stack unwinding only for allocated memory that can be lost if not freed properly in a case of exception? – Gilad Mar 02 '13 at 00:55
  • 1
    @Androidy: All cout statemenst get printed when they should not since in the first line in f() there is a throw and f() is the first call in main(). – Alex Net Mar 02 '13 at 00:56
  • @AlexNet but still in order to open the stack winding don't you need to allocate some memory? declare a class ? – Gilad Mar 02 '13 at 01:02
  • 1
    @Androidy : [A little reading](http://stackoverflow.com/q/2331316/636019) on your part might clear up your confusion... ;-] – ildjarn Mar 02 '13 at 01:03
  • @ildjarn funny I was just there this is why I'm asking about the memory allocation.I'm quoting: "This process of destroying local objects and calling destructors is called stack unwinding" – Gilad Mar 02 '13 at 01:04
  • I think this is strictly a MS visual C++ related issue - how MS wishes to deal in this situation. I can say with high degree of confidence that if, in Linux, the code is compiled using gcc and debugged using gdb we would not see the cout statements being printed. – Alex Net Mar 02 '13 at 01:09
  • @Androidy Try to answer this question, after the `throw 1` in f() should the next line of execution be the cout statements in f() ? and, after those, in main() ? – Alex Net Mar 02 '13 at 01:20
  • It's late here in the UK, so I will have to continue tomorrow. – Alex Net Mar 02 '13 at 01:22

2 Answers2

4

This is technically possible if you run with the debugger. You didn't tell the whole story though. The debugger will display a dialog first when the exception is thrown. It looks similar to this (mine is VS2012 on Windows 8):

enter image description here

If you click the Break button then the debugger will break at the throw statement, giving you a chance to inspect state. When you click the Continue button then the exception is ignored and the program will continue as though nothing happened. This also happens when you break and then resume running.

This is a feature, not a bug, it allows you to rescue a debug session on which you already spent a lot of time. It is of course not often that useful to continue since your program is likely to be in a bad state but the alternative isn't great either. You almost always want to favor clicking Break and use the debugger to correct state so that you can meaningfully continue debugging.

Of course this will never happen without a debugger, your program will instantly terminate.

The only possible way that a stack unwind is ever going to happen is by writing a catch clause that catches the exception. Regardless of whether you are debugging or not.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • @Passat It is all very well but the program should do whether in debugging mode or not what the code say it should do. A throw does not mean carry on to the next line of execution. When I am debugging how do I tell the debugger not to go to the next line of execution? This is just mad!! I write a program to do something and the debugger decides to do something else. – Alex Net Mar 02 '13 at 01:28
  • @Passant I wish not to write a try-catch - so how do I debug when a throw is invoked by the code? – Alex Net Mar 02 '13 at 01:35
  • Well, that's kinda nonsense. That's like a lumberjack complaining that his chainsaw cuts down the tree too fast. You've got a power tool at your disposal, learn how to use it so it won't cut your leg off. – Hans Passant Mar 02 '13 at 01:35
  • Click the Break button. That's the chainsaw off switch. – Hans Passant Mar 02 '13 at 01:36
  • To throw is a tool that is at my disposal and I wish to use it. I also want the program to just use the default mode of handling uncaught exceptions. This is the program I want see running when I am debugging - plain simple. How do I see it running under the debugger? – Alex Net Mar 02 '13 at 01:42
  • 1
    Use Debug + Stop Debugging. Boom, over. You sound a bit clueless about this, check your favorite C++ language book to see what is supposed to happen to a program that throws an exception that isn't being caught. Boom, over. Hopefully it will spend more words on that. – Hans Passant Mar 02 '13 at 01:51
  • I agree with Hans Passant - there's a whole lot of code that will use exceptions as part of the normal behaviour, you don't want the debugger breaking on every throw, which is why the VS2010 debugger allows you to select which exceptions are caught. – Roger Rowland Mar 02 '13 at 08:31
1

The key in answering my own question lies in answering another sub-question: right after an exception is thrown, at which point does the stack unwinding begin? By stack unwinding is meant the call, in reverse order, of destructors of all automatic objects that still exist. Answer: at the point the control is passed to the exception handler, i.e. the exception is caught. If the exception is not caught, the C++ exception mechanism dictates that the terminate function is to be called and this in effect by default calls abort(). This mechanism can be seen in action by the following code:

struct X {
    ~X() { std::cout << "~X !!\n"; }
};

int main(int, const char**) {
    X x; 
    throw 1;
    return 0;
}

After the throw, the destructor for X is never called because the no exception handler has gained control and so the program aborts. Back to the initial question, in the situation of when you are debugging a debug build and during execution of the program an exception is thrown when there is no suitable try-catch block around it, the MS Studio debugger breaks at the throw point and presents you with the dialogue window shown above and provides you with the option to “continue”. Continue is to be interpreted not as “carry on with the exception mechanism” but as “carry as if nothing has happened” i.e. with the next line of code after the throw.

Alex Net
  • 164
  • 12