views:

73

answers:

1

In VC++7 if I do the following:

void myTerminate()
{
    cout << "In myTerminate()";
    abort();
}

int main( int, char** )
{
    set_terminate( &myTerminate );
    set_terminate( 0 );
    terminate();
    return 0;
}

the program behaves exactly as if abort() was called directly which is exactly what default terminate() handler does.

If I omit the set_terminate( 0 ); statement my terminate handler is being called. So calling set_terminate( 0 ) seems to have the effect of resetting the terminate() handler to default.

Is this behavior specific to VC++7 only? Won't the program run into undefined behavior if I call set_terminate( 0 ) on some other implementation?

+5  A: 

Looking into the standard reveals the following:

terminate_handler set_terminate(terminate_handler f) throw();

1 Effects: Establishes the function designated by f as the current handler function ... cut
2 Requires: f shall not be a null pointer.
3 Returns: The previous terminate_handler.

Seems to be non-standard.

Alexander Gessler
Section 18.6.3.2 :)
Manuel
So it is unspecified behavior, isn't it?
sharptooth
Yes, it's undefined behaviour. You need to store the previous handler and recover it explicitly.
Alexander Gessler
@Alexander Gessler: to be precise, "unspecified behavior" != "undefined behavior", thus "no, it's undefined behavior".
Alexander Poluektov
(The difference is that "unspecified behavior" is used when the range of possible behaviors is limited. Some programs may tolerate any of the possible behaviors, hence unspecified behavior is not necessarily bad. Undefined Behavior never can be tolerated).
MSalters
@MSalters - interesting distinction, does the standard put it in those terms?
Manuel
MSalters
@MSalters, @Manuel: Yes it does (1.3.5, 1.3.12, 1.3.13)
Alexander Poluektov