tags:

views:

154

answers:

7

Following code will compile but crash at run time:

int main() {

    try {
        throw;
    }
    catch(...){
        cout<<"In catch";
    }
     return 0;

}

Result: “Unhandled exception at 0x7c812a5b in hello.exe: Microsoft C++ exception: [rethrow] @ 0x00000000”

Why compiler allows the code to compile? it looks not so difficult job for compiler to check if this code is part of catch block or not.

+3  A: 

Not so easy. You could have called this function from inside a catch block in some other function.

A concept of so-called exception handler is described in this answer.

sharptooth
main() cannot be called in C++
anon
At least in VC++7 it can be called. And the question doesn't insist on doing that specifically in main.
sharptooth
The C++ Standard forbids it.
anon
@Neil: Though technically correct. I am sure the compiler does not treat main() as special for checking in this context so it just looks like a function call, (and knowing windows they probably hash (pound for you Americans) defined it into something else).
Martin York
Does the C++ standard forbid implementations from allowing main() to be called, or does it merely forbid programmers from calling it. The language is, "main() shall not be called", but since I've never implemented a C++ compiler, I've never really needed to know what that language means for implementations. If MSVC wants to allow main() to be called, and if that's OK, then the objection doesn't apply.
Steve Jessop
To be irritatingly precise, the Standard says "The function main shall not be used", which is in many ways even more vague. My take is that if you want to write Standard compliant C++, you can't call main. Of course, lots of C++ is not remotely standard compliant.
anon
@onebyne: I have never come across a compiler that prevents main() being called.
Martin York
@Martin: not preventing it doesn't mean they support it -- the question is whether the compiler intends for programs which do it to have predictable behaviour. @Neil: yes, lots of C++ code uses extensions to the standard, for example when writing multi-threaded code, or relying on compiler-defined behaviour like "integers are 2's complement". I'm just idly curious whether defining the effect of calling main() is a valid way for an implementation to extend the standard without contradicting it.
Steve Jessop
(@Martin - sorry, if it isn't now obvious, by "allow" I meant "document the result of doing", i.e. explicitly permit. As opposed to "allow" meaning "not prevent". Compilers "allow" you to dereference a null pointer in the second sense, but neither compilers nor the C++ standard "allow" this in the first sense.
Steve Jessop
A: 

How should it know the caller of the function will not catch the exception?

Zed
main() cannot be called in C++
anon
+5  A: 

There are probably millions of errors that compilers could catch, if the compiler writers put enough work into them. But those compiler writers have to make judgements about whether that work is worthwhile. In this case, they decided not (and I agree with them).

anon
+2  A: 

You can put the throw in a function which is called from a catch block. Sometimes useful if you have a common handling for a class of exceptions:

void handleXExceptions()
{
   try {
      throw;
   } catch (XA&) {
      ...
   } catch (XB&) {
      ...
   } catch (X&) {
      assert("Update handleXExceptions" == NULL); 
   }
}

void f() {
   try {
      ...
   } catch (X&) {
      handleXExceptions();
   }
}

void g() {
   try {
      ...
   } catch (X&) {
      handleXExceptions();
   }
}
AProgrammer
Yeap, that's called an exception handler - http://stackoverflow.com/questions/980149/several-catch-blocks-or-one-with-dynamiccast/980347#980347
sharptooth
+2  A: 

Simply because the code is legal. You could say the same about:

int* p=0;
*p = 0;

and thousands of other examples. It's legal but very wrong.

markh44
A: 

Thanks, I think i got the point, it is something like throwing null exception (there is nothing to re throw) and compiler is not supposed to do null checks for us.

Learner
+5  A: 

From C++ Standard (15.1.8)

If no exception is presently being handled, executing a throw-expression with no operand calls std::terminate()

As standard allows it and gives clear semantics, a compiler can only conform to it.

Tadeusz Kopec
The standard allows lots of things that compiler writers may choose to give warnings about.
anon
The question was "Why compiler allows the code to compile?" It has to. Others gave examples where rethrowing in separate function may be useful. And creating special rules for checking main function, knowing it can't be called, is to much work for too little gain.
Tadeusz Kopec