2

I've got a class cnMeshHelper whose method cnMeshHelper::initialize calls various functions that may throw cnZeroDivisionException.
The stripped down code looks like this:

cnVector cnVector::getNormalized() {
    if (getLength() == 0.0) {
        #ifdef DEBUG
            printf("Throwing exception in cnVector::getNormalized().\n");
        #endif // DEBUG
        throw cnZeroDivisionException();
    }
    // ...
}

cnMatrix cnMatrix::getNormalized() {
    return cnMatrix(
        T.getNormalized(),
        B.getNormalized(),
        N.getNormalized(),
        M.getNormalized() );
}

cnMatrix cnComputeTangentSpace( /* ... */ ) {
    cnMatrix mat;
    // ...
    mat.T = mat.T.getNormalized()
    return mat;
}

void cnMeshHelper::initialize(cnMesh& mesh) {
    // ...
    polygonMatrix = cnComputeTangentSpace( /* ... */ );
}

int main() {
    cnMesh* mesh = new cnMesh( /* ... */ );
    // ...
    try {
        cnMeshHelper helper;
        helper.initialize(*mesh);
    }
    catch(cnZeroDivisionException& e) {
        cout << "Zero division exceptione caught.\n";
    }
}

Now, in some cases, it can happen that the cnMesh* mesh has invalid values that cause to throw an exception in cnVector::getNormalized().
But the problem is, if this is the case, the try-catch clause does not catch the exception. The program just terminates after printing the DEBUG-text in the method above.

Update: Note that I can catch the exception within cnMeshHelper::initialize() but everything "outer" doesn't work.
Even using catch(...) does not work in the main.

Can you tell me why the exception isn't caught ?

Got it !

It happens often, that the issue lies somewhere else. So in this case, too.
The cnMeshHelper destructor throwed a null-pointer because of an uninitialized member. The member was uninitialized because of the cnZeroDivisionException in cnMeshHelper::initialize.
Thanks for you help, anyway.

Niklas R
  • 16,299
  • 28
  • 108
  • 203
  • 3
    Executing printf in your code doesn't mean that exception is thrown. There is if operator after prinf. – Alex F Oct 29 '11 at 09:50
  • 1
    Have you checked in debugger that exception is do thrown? – ks1322 Oct 29 '11 at 09:54
  • @AlexFarber Thanks, that was just an issue of mine when writing this question. Corrected it. – Niklas R Oct 29 '11 at 10:01
  • 1
    You should never allow an exception to escape a destructor. See this question: http://stackoverflow.com/questions/130117/throwing-exceptions-out-of-a-destructor – bames53 Oct 31 '11 at 17:45

3 Answers3

1

The part

catch(cnZeroDivisionException& e) {

will catch exactly one kind of exception. But what happens if there is another exception or a non-exception abort (dereferencing NULL, ...)?

So please move the printf into the if sections to see if really an exception of the right type is thrown.

My crystal ball guess is that getLength will reveal something bad since you wrote

...it can happen that the cnMesh* mesh has invalid values...

These invalid values might affect getLength also in some way. (nullpointers, uninitialized memory, other exceptions, ...)

A.H.
  • 63,967
  • 15
  • 92
  • 126
  • Sorry, I should add this to the question as well. Catching the ZeroDivisionException within the cnMeshHelper::initalize works, everything outer doesn't. I have already moved the `printf` into the if-statement, was my issue when writing the question – Niklas R Oct 29 '11 at 10:13
1

Got it !

It happens often, that the issue lies somewhere else. So in this case, too. The cnMeshHelper destructor throwed a null-pointer because of an uninitialized member. The member was uninitialized because of the cnZeroDivisionException in cnMeshHelper::initialize. Thanks for you help, anyway.

Niklas R
  • 16,299
  • 28
  • 108
  • 203
0

Does any of the functions involved have exception specifications (void fn() throw(some_exception))? They will abort the program if an exception that doesn't match the specification is thrown.

I repeat the previous advice of stepping through the code with a debugger.

Baffe Boyois
  • 2,120
  • 15
  • 15
  • Where should I add `..() throw(some_exception) ..` ? Only the method that throws or any method that may call the throwing methods ? – Niklas R Oct 29 '11 at 10:50