fbpx
Wikipedia

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[1]​ 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[1]​ 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],[2]​ 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.[3][4]

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.[5]​ 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".

#include <stdio.h> #include <setjmp.h> static jmp_buf buf; void second(void) {  printf("second\n"); // Impresiones  longjmp(buf,1); // salta de nuevo a donde fue llamado setjmp } void first(void) {  second();  printf("first\n"); // No se Imprime } int main() {   if ( ! setjmp(buf) ) {  first(); // Cuando se ejecuta, devuelve 0 setjmp  } else { // cuando salta longjmp, setjmp devuelve 1  printf("main\n"); // Impresiones  }  return 0; } 

Manejo de excepciones

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <setjmp.h>   void first(void); void second(void);   /* This program's output is:   calling first calling second entering second second failed with type 3 exception; remapping to type 1. first failed, exception type 1   */   /* Use a file scoped static variable for the exception stack so we can access  * it anywhere within this translation unit. */ static jmp_buf exception_env; static int exception_type;   int main() {  void *volatile mem_buffer;    mem_buffer = NULL;  if (setjmp(exception_env)) {  /* if we get here there was an exception */  printf("first failed, exception type %d\n", exception_type);  } else {  /* Run code that may signal failure via longjmp. */  printf("calling first\n");  first();  mem_buffer = malloc(300); /* allocate a resource */  printf(strcpy((char*) mem_buffer, "first succeeded!")); /* ... this will not happen */  }  if (mem_buffer)  free((void*) mem_buffer); /* carefully deallocate resource */  return 0; }   void first(void) {  jmp_buf my_env;    printf("calling second\n");  memcpy(my_env, exception_env, sizeof(jmp_buf));  switch (setjmp(exception_env)) {  case 3:  /* if we get here there was an exception. */  printf("second failed with type 3 exception; remapping to type 1.\n");  exception_type = 1;  default: /* fall through */  memcpy(exception_env, my_env, sizeof(jmp_buf)); /* restore exception stack */  longjmp(exception_env, exception_type); /* continue handling the exception */  case 0:  /* normal, desired operation */  second();  printf("second succeeded\n"); /* not reached */  }  memcpy(exception_env, my_env, sizeof(jmp_buf)); /* restore exception stack */ }   void second(void) {  printf("entering second\n" ); /* reached */  exception_type = 3;  longjmp(exception_env, exception_type); /* declare that the program has failed */  printf("leaving second\n"); /* not reached */ } 

Multitarea cooperativa

#include <setjmp.h> #include <stdio.h> jmp_buf mainTask, childTask; void call_with_cushion(void); void child(void); int main(void) {  if (!setjmp(mainTask)) {  call_with_cushion(); /* child never returns */ /* yield */  } /* execution resumes after this "}" after first time that child yields */  for (;;) {  printf("Parent\n");  if (!setjmp(mainTask)) {  longjmp(childTask, 1); /* yield - note that this is undefined under C99 */  }  } } void call_with_cushion (void) {  char space[1000]; /* Reserve enough space for main to run */  space[999] = 1; /* Do not optimize array out of existence */  child(); } void child (void) {  for (;;) {  printf("Child loop begin\n");  if (!setjmp(childTask)) longjmp(mainTask, 1); /* yield - invalidates childTask in C99 */  printf("Child loop end\n");  if (!setjmp(childTask)) longjmp(mainTask, 1); /* yield - invalidates childTask in C99 */  }  /* Don't return. Instead we should set a flag to indicate that main()  should stop yielding to us and then longjmp(mainTask, 1) */ } 

Referencias

  1. ISO C establece que setjmp debe ser implementado como una macro, pero POSIX establece explícitamente que no está definido si setjmp es una macro o una función.
  2. Este es el tipo usado por Glibc, versión 2.7
  3. CS360 Lecture Notes — Setjmp and Longjmp
  4. setjmp(3) el 26 de julio de 2009 en Wayback Machine.
  5. ISO/IEC 9899:1999, 2005, 7.13.2.1:2 y nota al pie 211

Enlaces externos

  • setjmp(3): save stack context for non-local goto – Subrutinas en el Manual de Debian
  • Exceptions in C with Longjmp and Setjmp
  •   Datos: Q307160

setjmp, este, artículo, sección, sobre, informática, necesita, wikificado, favor, edítalo, para, cumpla, convenciones, estilo, este, aviso, puesto, junio, 2011, encabezado, definido, biblioteca, estándar, para, proporcionar, saltos, locales, control, flujo, de. Este articulo o seccion sobre informatica necesita ser wikificado por favor editalo para que cumpla con las convenciones de estilo Este aviso fue puesto el 8 de junio de 2011 setjmp h es un encabezado definido en la biblioteca estandar de C para proporcionar saltos no locales control de flujo que se desvia de la llamada a subrutina habitual y la secuencia de retorno Las funciones complementarias setjmp y longjmp proporcionan esta funcionalidad Un uso tipico de setjmp longjmp es la implementacion de un mecanismo de excepcion que utiliza la capacidad de longjmp para restablecer el estado del programa o hilo incluso a traves de multiples niveles de las llamadas a funciones Un uso menos comun de setjmp es crear una sintaxis similar a corrutinas Indice 1 Funciones miembro 2 Tipos Miembro 3 Advertencias y limitaciones 4 Ejemplos de uso 4 1 Ejemplo simple 4 2 Manejo de excepciones 4 3 Multitarea cooperativa 5 Referencias 6 Enlaces externosFunciones miembro Editarint setjmp jmp buf env Establece el buffer jmp buf local y lo inicializa para el salto Esta rutina 1 guarda el contexto de la llamada del programa en el bufer de contexto especificado por el argumento env para su uso posterior por longjmp Si el retorno es de una invocacion 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 salvo por invocacion de la rutina 1 en la misma invocacion del programa Invocando longjmp desde un manejador de senales anidado no definido El valor especificado por valor es pasado desde longjmp a setjmp Despues de que longjmp se completa la ejecucion del programa continua como si la invocacion correspondiente de setjmp acabara de regresar Si el valor pasado a longjmp es 0 setjmp se comportara como si hubiera devuelto 1 de lo contrario se comportara como si hubiera devuelto un valor setjmp guarda el contexto actual Ej el estado del programa en algun punto de la ejecucion del programa en una estructura de datos especifica de la plataforma jmp buf que puede ser usada en un punto mas lejano de la ejecucion 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 atras hacia el punto de la ejecucion 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 comun idioma if setjmp x manejar longjmp x POSIX 1 no especifica si setjmp y longjmp guardan o restauran el conjunto actual de bloqueo de senales si un programa cuenta con manejo de senales que deberia usarlas instrucciones POSIX sigsetjmp siglongjmp Tipos Miembro Editarjmp buf Un tipo de array como struct jmp buf tag 1 2 apropiado para manejar la informacion necesaria para restaurar el contexto desde una llamada a sistema Advertencias y limitaciones EditarCuando un goto no local se ejecuta a traves 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 buferes la liberacion de la memoria asignada en el heap etc no ocurren Si la funcion en la que fue llamada setjmp retorna ya no es posible utilizar de forma segura longjmp con el objeto jmp buf correspondiente Esto es asi porque el marco de pila se invalida cuando se devuelve la funcion Llamar a longjmp restablece el puntero de pila que ya que la funcion retorna apuntaria a un marco de pila inexistente y posiblemente sobrescrito o danado 3 4 Del mismo modo C99 no requiere que longjmp preserve el marco de pila actual Esto significa que saltar a una funcion que sale a traves de una llamada a longjmp no esta definido 5 Sin embargo la mayoria de las implementaciones de longjmp dejan intacto el marco de pila lo que permite a setjmp y longjmp ser utilizados para saltar hacia atras y hacia adelante entre dos o mas funciones una caracteristica explotada para la multitarea En comparacion con los mecanismos de lenguajes de programacion de alto nivel como Python Java C C e incluso lenguajes pre C como Algol 60 la tecnica de usar setjmp longjmp para implementar un mecanismo de excepcion es engorrosa Estos lenguajes proporcionan tecnicas de manejo de excepciones mas potentes mientras que lenguajes como Scheme Smalltalk y Haskell proporcionan construcciones de manejo de continuidad incluso mas generales Ejemplos de uso EditarEjemplo simple Editar Este ejemplo muestra la idea basica de setjmp La funcion main llama a first la cual a su vez llama a second La funcion second salta de vuelta a la funcion main omitiendo la ejecucion de la instruccion printf de la funcion first include lt stdio h gt include lt setjmp h gt static jmp buf buf void second void printf second n Impresiones longjmp buf 1 salta de nuevo a donde fue llamado setjmp void first void second printf first n No se Imprime int main if setjmp buf first Cuando se ejecuta devuelve 0 setjmp else cuando salta longjmp setjmp devuelve 1 printf main n Impresiones return 0 Manejo de excepciones Editar include lt stdio h gt include lt stdlib h gt include lt string h gt include lt setjmp h gt void first void void second void This program s output is calling first calling second entering second second failed with type 3 exception remapping to type 1 first failed exception type 1 Use a file scoped static variable for the exception stack so we can access it anywhere within this translation unit static jmp buf exception env static int exception type int main void volatile mem buffer mem buffer NULL if setjmp exception env if we get here there was an exception printf first failed exception type d n exception type else Run code that may signal failure via longjmp printf calling first n first mem buffer malloc 300 allocate a resource printf strcpy char mem buffer first succeeded this will not happen if mem buffer free void mem buffer carefully deallocate resource return 0 void first void jmp buf my env printf calling second n memcpy my env exception env sizeof jmp buf switch setjmp exception env case 3 if we get here there was an exception printf second failed with type 3 exception remapping to type 1 n exception type 1 default fall through memcpy exception env my env sizeof jmp buf restore exception stack longjmp exception env exception type continue handling the exception case 0 normal desired operation second printf second succeeded n not reached memcpy exception env my env sizeof jmp buf restore exception stack void second void printf entering second n reached exception type 3 longjmp exception env exception type declare that the program has failed printf leaving second n not reached Multitarea cooperativa Editar include lt setjmp h gt include lt stdio h gt jmp buf mainTask childTask void call with cushion void void child void int main void if setjmp mainTask call with cushion child never returns yield execution resumes after this after first time that child yields for printf Parent n if setjmp mainTask longjmp childTask 1 yield note that this is undefined under C99 void call with cushion void char space 1000 Reserve enough space for main to run space 999 1 Do not optimize array out of existence child void child void for printf Child loop begin n if setjmp childTask longjmp mainTask 1 yield invalidates childTask in C99 printf Child loop end n if setjmp childTask longjmp mainTask 1 yield invalidates childTask in C99 Don t return Instead we should set a flag to indicate that main should stop yielding to us and then longjmp mainTask 1 Referencias Editar a b ISO C establece que setjmp debe ser implementado como una macro pero POSIX establece explicitamente que no esta definido si setjmp es una macro o una funcion Este es el tipo usado por Glibc version 2 7 CS360 Lecture Notes Setjmp and Longjmp setjmp 3 Archivado el 26 de julio de 2009 en Wayback Machine ISO IEC 9899 1999 2005 7 13 2 1 2 y nota al pie 211Enlaces externos Editarsetjmp 3 save stack context for non local goto Subrutinas en el Manual de Debian Exceptions in C with Longjmp and Setjmp Datos Q307160 Obtenido de https es wikipedia org w index php title Setjmp h amp oldid 128823632, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos