with try son que las instrucciones example catch c++ c exception-handling try-catch ansi-c

c++ - son - ANSI C equivalente de try/catch?



try catch en c (8)

Tengo algunos códigos C con los que trabajo, y encuentro errores cuando el código se está ejecutando, pero tengo poca información sobre cómo realizar un intento / captura (como en C # o C ++).

Por ejemplo en C ++ acabo de hacer:

try{ //some stuff } catch(...) { //handle error }

Pero en ANSI C estoy un poco perdido. Intenté algunas búsquedas en línea, pero no veo suficiente información sobre cómo hacer que suceda / pensé que preguntaría aquí en caso de que alguien pueda indicarme la dirección correcta.

Aquí está el código con el que estoy trabajando (método bastante simple y recursivo) y me gustaría envolverlo con try / catch (o una estructura de manejo de errores equivalente).

Sin embargo, mi pregunta principal es simplemente cómo hacer un try / catch en ANSI C ... la implementación / ejemplo no tiene por qué ser recursiva.

void getInfo( int offset, myfile::MyItem * item ) { ll::String myOtherInfo = item->getOtherInfo(); if( myOtherInfo.isNull() ) myOtherInfo = ""; ll::String getOne = ""; myfile::Abc * abc = item->getOrig(); if( abc != NULL ) { getOne = abc->getOne(); } for( int i = 0 ; i < offset ; i++ ) { printf("found: %d", i); } if( abc != NULL ) abc->release(); int childCount = item->getChildCount(); offset++; for( int i = 0 ; i < childCount ; i++ ) getInfo( offset, item->getChild(i) ); item->release(); }


C no admite el manejo de excepciones.

Hay información sobre un enfoque de este problema here . Esto muestra el enfoque setjmp/longjmp simple pero también proporciona una alternativa más sofisticada, cubierta en profundidad.


Dado que C ++ se implementó originalmente como un preprocesador C y tenía Try / Catch, podría rehacer el trabajo de Bjarne Stroustrup y escribir un preprocesador para hacerlo.


En general, no lo haces.

Es posible usar setjmp y longjmp para construir algo bastante similar a try / catch, aunque no hay tal cosa en C como los destructores o el desenrollado de la pila, por lo que RAII está fuera de discusión. Incluso podría aproximarse a RAII con una llamada "pila de limpieza" (vea por ejemplo Symbian / C ++), aunque no es una aproximación muy cercana, y es mucho trabajo.

La forma habitual de indicar errores o fallas en C es devolver un valor que indique el estado de éxito. Las personas que llaman examinan el valor de retorno y actúan en consecuencia. Vea, por ejemplo, las funciones estándar de C: printf , read , open , para obtener ideas sobre cómo especificar sus funciones.

Al mezclar código C y C ++, debe asegurarse de que una excepción de C ++ nunca alcance el código C. Al escribir funciones de C ++ que se llamarán desde C, captura todo.


Esta es mi implementación de un sistema de manejo de excepciones en C: exceptions4c .

Es alimentado por macros, construido sobre setjmp y longjmp y es 100% ANSI C portátil.

There también puede encontrar una lista de todas las diferentes implementaciones que conozco.


Existe el clásico patrón de desenrollar goto s:

FILE *if = fopen(...); FILE *of = NULL; if (if == NULL) return; of = fopen(...); if (of == NULL) goto close_if; /* ...code... */ if (something_is_wrong) goto close_of; /* ... other code... */ close_of: fclose(of); close_if: fclose(if); return state;

Alternativamente, puedes simularlo de forma limitada aislando el código "try" en otra función

int try_code(type *var_we_must_write, othertype var_we_only_read /*, ... */){ /* ...code... */ if (!some_condition) return 1; /* ...code... */ if (!another_condition) return 2; /* ...code... */ if (last_way_to_fail) return 4; return 0; } void calling_routine(){ /* ... */ if (try_code(&x,y/*, other state */) ) { /* do your finally here */ } /* ... */ }

pero ninguno de los dos enfoques es totalmente equivalente. Usted mismo debe administrar todos los recursos, no obtiene la reversión automática hasta que se encuentra un manejador, y así sucesivamente ...



Si desea realizar un salto de varios niveles, busque setjmp() y longjmp() . Se pueden usar como un lanzamiento de excepción primitivo. La función setjmp() configura un lugar de retorno y devuelve un valor de estado. La función longjmp() va al lugar de retorno y proporciona el valor de estado. Puede crear una función catch al ser llamada después de setjmp() dependiendo del valor de estado.

No, por el motivo que sea, utilícelos en C ++. No hacen el desenrollado de la pila o llaman a los destructores.


Un estilo de codificación útil que me gusta usar es el siguiente. No sé si tiene un nombre en particular, pero lo encontré cuando estaba realizando ingeniería inversa en un código de ensamblaje en el código C equivalente. Usted pierde un nivel de sangría pero no es tan importante para mí. ¡Cuidado con el crítico que señala el bucle infinito! :)

int SomeFunction() { int err = SUCCESS; do { err = DoSomethingThatMayFail(); if (err != SUCCESS) { printf("DoSomethingThatMayFail() failed with %d", err); break; } err = DoSomethingElse(); if (err != SUCCESS) { printf("DoSomethingElse() failed with %d", err); break; } // ... call as many functions as needed. // If execution gets there everything succeeded! return SUCCESS; while (false); // Something went wrong! // Close handles or free memory that may have been allocated successfully. return err; }