Setjmp.h
# Setjmp.h

setjmp.h es un encabezado definido en la biblioteca estándar de C para proporcionar "saltos no locales": control de flujo que se desvía de la llamada a subrutina habitual y la secuencia de retorno. Las funciones complementarias setjmp y longjmp proporcionan esta funcionalidad.

Un uso típico de setjmp/longjmp es la implementación de un mecanismo de excepción que utiliza la capacidad de longjmp para restablecer el estado del programa o hilo, incluso a través de múltiples niveles de las llamadas a funciones. Un uso menos común de setjmp es crear una sintaxis similar a corrutinas.

## Funciones miembro

| int setjmp(jmp_buf env) | Establece el buffer jmp_buf local y lo inicializa para el salto. Esta rutina guarda el contexto de la llamada del programa en el búfer de contexto especificado por el argumento env para su uso posterior por longjmp. Si el retorno es de una invocación directa, setjmp devuelve 0. Si el retorno es de una llamada a longjmp, setjmp devuelve un valor distinto de cero. |
| - | - |
| void longjmp(jmp_buf env, int value) | Restaura el contexto del buffer de entorno env que se salvó por invocación de la rutina en la misma invocación del programa. Invocando longjmp desde un manejador de señales anidado no definido. El valor especificado por valor es pasado desde longjmp a setjmp. Después de que longjmp se completa, la ejecución del programa continúa como si la invocación correspondiente de setjmp acabara de regresar. Si el valor pasado a longjmp es 0, setjmp se comportará como si hubiera devuelto 1;, de lo contrario, se comportará como si hubiera devuelto un valor. |

setjmp guarda el contexto actual (Ej., el estado del programa) en algún punto de la ejecución del programa, en una estructura de datos específica de la plataforma (jmp_buf) que puede ser usada, en un punto más lejano de la ejecución del programa, por longjmp para restaurar el estado del programa que fue guardado por setjmp en jmp_buf. Este proceso puede representarse como un "salto" atrás hacia el punto de la ejecución del programa donde setjmp guardo el contexto. El (aparente) valor de retorno de setjmp indica si el control alcanzado el punto de normalidad o de una llamada a longjmp . Esto lleva a un común idioma: if( setjmp(x) ){/* manejar longjmp(x) */}.

POSIX.1 no especifica si setjmp y longjmp guardan o restauran el conjunto actual de bloqueo de señales — si un programa cuenta con manejo de señales que debería usarlas instrucciones POSIX sigsetjmp/siglongjmp .

## Tipos Miembro

| jmp_buf | Un tipo de array, como struct __jmp_buf_tag[1], apropiado para manejar la información necesaria para restaurar el contexto desde una llamada a sistema. |
| - | - |

## Advertencias y limitaciones

Cuando un "goto no-local" se ejecuta a través de setjmp / longjmp, el "desenrolle de pila" normal no ocurre y por lo tanto, las acciones de limpieza necesarios, tales como el cierre de descriptores de archivos, el vaciado de los búferes, la liberación de la memoria asignada en el heap, etc., no ocurren.

Si la función en la que fue llamada setjmp retorna, ya no es posible utilizar de forma segura longjmp con el objeto jmp_buf correspondiente. Esto es así porque el marco de pila se invalida cuando se devuelve la función. Llamar a longjmp restablece el puntero de pila, que -ya que la función retorna- apuntaría a un marco de pila inexistente y posiblemente sobrescrito o dañado.

Del mismo modo, C99 no requiere que longjmp preserve el marco de pila actual. Esto significa que saltar a una función que sale a través de una llamada a longjmp no está definido. Sin embargo, la mayoría de las implementaciones de longjmp dejan intacto el marco de pila, lo que permite a setjmp y longjmp ser utilizados para saltar hacia atrás y hacia adelante entre dos o más funciones -una característica explotada para la multitarea-.

En comparación con los mecanismos de lenguajes de programación de alto nivel como Python, Java, C + +, C #, e incluso lenguajes pre-C como Algol 60, la técnica de usar setjmp / longjmp para implementar un mecanismo de excepción es engorrosa. Estos lenguajes proporcionan técnicas de manejo de excepciones más potentes, mientras que lenguajes como Scheme, Smalltalk, y Haskell proporcionan construcciones de manejo de continuidad incluso más generales.

## Ejemplos de uso

### Ejemplo simple

Este ejemplo muestra la idea básica de setjmp. La función main llama a first, la cual a su vez llama a second. La función "second" salta de vuelta a la función main, omitiendo la ejecución de la instrucción printf de la función "first".

