2009-09-03 11 views
32

¿Es seguro usar longjmp y setjmp en C++ en linux/gcc con respecto a lo siguiente?C++: ¿es seguro usar longjmp y setjmp?

  1. manejo de excepciones (no estoy implementar el manejo de excepciones usando longjmp/setjmp. Quiero saber qué efectos secundarios longjmp/setjmp tendrá en el manejo de excepciones estándar)
  2. *this puntero
  3. señales
  4. Punteros inteligentes (punteros compartidos e intrusivos de boost)
  5. Cualquier otra cosa que se te ocurra.

Respuesta

54

setjmp()/longjmp() desarman completamente el desenrollado de la pila y, por lo tanto, el manejo de excepciones, así como RAII (destructores en general).

De 18.7/4 "Otro soporte de ejecución" en la norma:

Si algún objeto automáticos serían destruidos por una excepción lanzada transferir control a otro (destino) punto en el programa, a continuación, una llamada a longjmp(jbuf, val) en el punto de lanzamiento que transfiere el control al mismo punto (destino) tiene un comportamiento indefinido.

Así que la conclusión es que setjmp()/longjmp() no juegan bien en C++.

+0

¿Puede explicar cómo longjmp ensucia con la eliminación explícita de memoria y los destructores? – jameszhao00

+12

Generalmente, cada vez que hay alguna forma de salir de un ámbito en C++ (retorno, tiro, o lo que sea), el compilador colocará instrucciones para llamar a los dtors para cualquier variable automática que deba destruirse como resultado de abandonar ese bloque. 'longjmp()' simplemente salta a una nueva ubicación en el código, por lo que no brindará ninguna posibilidad de invocar a los controladores. El estándar es en realidad menos específico que eso: el estándar no dice que no se llamarán dtors, dice que todas las apuestas están desactivadas. No puede depender de ningún comportamiento en particular en este caso. –

+0

No estoy muy familiarizado con los punteros inteligentes. Si tengo un puntero inteligente en la pila, cuando hago un salto largo, ¿significa eso que el puntero inteligente no eliminará un recuento? Además, ¿estoy a salvo si deshabilito las excepciones y escribo código que no se vuelve loco con longjmp? – jameszhao00

-8

Solo he aprendido sobre esos comandos, y nunca los he visto en acción en aplicaciones reales.

En mi humilde opinión, es seguro decir que no es seguro usarlos: los desarrolladores no entenderán lo que hacen esas API "impopulares".

+3

Esto es para una implementación de coroutines (que requiere saltos aleatorios) – jameszhao00

+11

Los desarrolladores con experiencia sabrán absolutamente qué hacen estas API "impopulares". Han sido parte de la biblioteca estándar de C durante décadas. – Novelocrat

+23

Los desarrolladores con experiencia sabrán absolutamente qué hacen estas funciones. También sabrán que son cosas difíciles de usar en C (aunque a veces son necesarias) y extremadamente peligrosas en C++. –

5

No es específico de Linux o gcc; setjmp/longjmp y C++ no funcionan demasiado bien si está usando longjmp para dejar un contexto donde hay variables automáticas con destructores.

Los destructores no se ejecutarán, lo que puede provocar una pérdida de memoria u otro comportamiento incorrecto.

Cuestiones relacionadas