// Tests for providing new default operations. #include #include DATA_EXCEPTION(log_message)( char * msg; ); void ?{}(log_message & this, char * msg) { VTABLE_INIT(this, log_message); this.msg = msg; } char * get_log_message(log_message * this) { return this->msg; } VTABLE_INSTANCE(log_message)(get_log_message); // Logging messages don't have to be handled. void defaultResumptionHandler(log_message &) {} // And should never be used to terminate computation. void defaultTerminationHandler(log_message &) = void; void log_test(void) { // We can catch log: try { throwResume (log_message){(char *)"Should be printed.\n"}; } catchResume (log_message * this) { printf(this->virtual_table->msg(this)); } // But we don't have to: throwResume (log_message){(char *)"Should not be printed.\n"}; } // I don't have a good use case for doing the same with termination. TRIVIAL_EXCEPTION(jump); void defaultTerminationHandler(jump &) { printf("jump default handler.\n"); } void jump_test(void) { try { throw (jump){}; } catch (jump * this) { printf("jump catch handler.\n"); } throw (jump){}; } TRIVIAL_EXCEPTION(first); TRIVIAL_EXCEPTION(unhandled_exception); void unhandled_test(void) { forall(dtype T | is_exception(T)) void defaultTerminationHandler(T &) { throw (unhandled_exception){}; } void defaultTerminationHandler(unhandled_exception &) { abort(); } try { throw (first){}; } catch (unhandled_exception * t) { printf("Catch unhandled_exception.\n"); } } int main(int argc, char * argv[]) { log_test(); jump_test(); unhandled_test(); }