Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Why standard C++ doesn't respect system (foreign or hardware) exceptions?

E.g. when null pointer dereference occurs, stack isn't unwound, destructors aren't called, and RAII doesn't work.

The common advice is "to use system API". But on certain systems, specifically Win32, this doesn't work. To enable stack unwinding for this C++ code

// class Foo;
// void bar(const Foo&);
bar(Foo(1, 2));

one should generate something like this C code

Foo tempFoo;
Foo_ctor(&tempFoo);
__try {
    bar(&tempFoo);
}
__finally {
    Foo_dtor(&tempFoo);
}
Foo_dtor(&tempFoo);

and it's impossible to implement this as C++ library.


Upd: Standard doesn't forbid handling system exceptions. But it seems that popular compilers like g++ doesn't respect system exceptions on any platforms just because standard doesn't require this.

The only thing that I want - is to use RAII to make code readable and program reliable. I don't want to put hand-crafted try\finally around every call to unknown code. For example in this reusable code, AbstractA::foo is such unknown code:

void func(AbstractA* a, AbstractB* b) {
    TempFile file;
    a->foo(b, file);
}

Maybe one will pass to func such implementation of AbstractA, which every Friday will not check if b is NULL, so access violation will happen, application will terminate and temporary file will not be deleted. How many months uses will suffer because of this issue, until either author of func or author of AbstractA will do something with it?


Related: Is `catch(...) { throw; }` a bad practice?

share|improve this question

3 Answers 3

As a C++ programmer I am glad that hardware exceptions are completely different things.

Imagine if they were not. Suddenly, code that has no throw statements in it is now throwing an exception. It might even be coming from inside a function which is declared as throw() or nothrow.

Besides that, in order to handle these exceptions properly, the programmer must know the hardware and platform quite well. In that case, he may as well use the platform provided functions to handle it. Just writing a catch block does not come anywhere close to properly fixing a bad pointer reference or a division-by-zero.

share|improve this answer
    
throw() works in run-time, so it's not an issue. nothrow works in compile-time, so yes, with hardware exceptions we can't use it. Regarding to complexity, just imagine that x->y works as x ? x->y : throw_null_pointer_dereference() –  Abyx Jun 8 '12 at 1:47

The C++ standard doesn't respect system exceptions because it was designed to be usable on a wide range of platforms (much wider that PC-based platforms). It would be impossible to provide some sort of support for each of the platform in the standard. This is left for implementations and rightfully so.

My reaction to the rant part of your question: Win32 exceptions are thrown in fatal cases from which you can't really recover. __try & friends does work in C++ as well (not only for C), and you can manually call the destructor if you need to (but your program is in a state where it won't run anymore, so unless that destructor releases something the OS wouldn't normally release after the process terminated, there isn't much point).

Edit: In answer to your update: You are still ranting. It's not how you imagined it, so what? You can still protect yourself against the scenario you cited as an example. You use the platform-specific code to catch the system exception, close the file and crash gracefully. There might be a better way to do this; ask a specific question on SO. Isolating 3rd party code is not trivial and likely requires some effort to achieve (a good example of this is the famously unstable flash plugin which now runs isolated in most major browsers).

g++ doesn't respect system exceptions on any platforms just because standard doesn't require this

Even though it does implement a good number of extensions, gcc targets architectures, not platforms. Gcc itself is ported to different platforms but that's a different story; the code-generation part is architecture-dependent, not platform-dependent. This explains why it wouldn't be possible to support windows system exceptions without great effort.

share|improve this answer
    
Why not to use system exceptions wherever it's possible, instead of not to use them at all? –  Abyx Dec 7 '11 at 15:10
    
@Abyx: Then it's implementation defined, and thus not standard C++. In fact, since behaviour is undefined in most (or even all?) error conditions like null pointer dereference, every implementation is free to do something like that. If they don't, perhaps they agree with my gut feeling that your code is screwed anyway if such errors occur, and it's likely because your code is broken. –  delnan Dec 7 '11 at 15:17
    
"Win32 exceptions are thrown in fatal cases from which you can't really recover" - it's incorrect. In VC++ all exceptions are implemented as system exceptions, and they definitely are non-fatal. Also, memory access violation can be non-fatal exceptions, nothing fatal will happen if replace if (p) with try block. –  Abyx Dec 7 '11 at 15:22
    
@delnan why my code? It can be third party dynamically linked code (plugin). –  Abyx Dec 7 '11 at 15:25
2  
@Abyx: They can be non-fatal, but in reality, they virtually always are. You need to process isolate third-party code if you wan to be protected from them. –  DeadMG Dec 7 '11 at 15:29

You can configure MSVC to catch system exceptions in a catch(...) block. This is exactly as the Standard intended- implementations provide mechanisms to catch errors thrown by their implementations. Strictly speaking, it's just UB and they don't have to provide any mechanism.

However, there's an increasing trend, both within and outside Microsoft, to not defensively code- for example IsBadXXXPtR is now heavily discouraged.

share|improve this answer
    
And there even is a function in the Microsoft CRT that allows you to convert system exceptions to C++ exceptions: msdn.microsoft.com/en-us/library/5z4bw5h5.aspx –  Patrick Dec 7 '11 at 15:32
    
There is no problem with MSVC, but I want to use g++ and other compilers, which doesn't support SEH on Windows. –  Abyx Dec 7 '11 at 15:58
    
@Patrick, this function works only for MSVC. –  Abyx Dec 7 '11 at 16:12
    
And I'm not talking about catch, I'm about RAII. –  Abyx Dec 7 '11 at 16:12
1  
@Abyx: It's not the Standard's fault that the implementation is deficient. Also, MSVC does call destructors when system exceptions are caught with catch(...). –  DeadMG Dec 8 '11 at 6:44

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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