Setjmp.h

De la Viquipèdia, l'enciclopèdia lliure
Setjmp.h

TipusC header file (en) Tradueix Modifica el valor a Wikidata
Part deC standard library, Biblioteca C POSIX i Biblioteca estàndard de C++ Modifica el valor a Wikidata
Característiques tècniques
PlataformaC standard library

setjmp.h és una capçalera definida a la biblioteca estàndard C per proporcionar "salts no locals": flux de control que es desvia de la seqüència de trucada i retorn de subrutina habitual. Les funcions complementàries setjmp i longjmp proporcionen aquesta funcionalitat.[1]

Un ús típic de setjmp / longjmp és la implementació d'un mecanisme d'excepció que explota la capacitat de longjmp per restablir l'estat del programa o del fil, fins i tot a través de diversos nivells de trucades de funció. Un ús menys comú de setjmp és crear una sintaxi semblant a les corrutines.[2]

int
setjmp(jmp_buf env)
Configura el buffer local jmp_buf i l'inicia per al salt. Aquesta rutina desa l'entorn de crida del programa a la memòria intermèdia d'entorn especificada per l'argument env per al seu ús posterior per longjmp. Si el retorn prové d'una invocació directa, setjmp retorna 0. Si el retorn és d'una trucada a longjmp, setjmp retorna un valor diferent de zero.
void
longjmp(jmp_buf env, int value)
Restaura el context del buffer d'entorn env que es va desar mitjançant la invocació de la rutina setjmp en la mateixa invocació del programa. Invocar longjmp des d'un controlador de senyal imbricat no està definit. El valor especificat per value es passa de longjmp a setjmp. Un cop finalitzat longjmp, l'execució del programa continua com si la corresponent invocació de setjmp acabés de tornar. Si el value passat longjmp és 0, setjmp es comportarà com si hagués retornat 1; en cas contrari, es comportarà com si hagués retornat value.

setjmp desa l'entorn actual (l'estat del programa), en algun moment de l'execució del programa, en una estructura de dades específica de la plataforma (jmp_buf ) que es pot utilitzar en algun moment posterior de l'execució del programa per longjmp per restaurar l'estat del programa al desat per setjmp a jmp_buf. Es pot imaginar que aquest procés és un "salt" de tornada al punt d'execució del programa on setjmp va salvar l'entorn. El valor de retorn (aparent) de setjmp indica si el control ha arribat a aquest punt normalment (zero) o des d'una trucada a longjmp (no zero). Això condueix a un modisme comú: if( setjmp(x) ){/* handle longjmp(x) */}.[3]

POSIX.1 no especifica si setjmp i longjmp guarden i restauren el conjunt actual de senyals bloquejats; si un programa utilitza el maneig de senyal, hauria d'utilitzar sigsetjmp / siglongjmp de POSIX.[4]

Funcions membre[modifica]

Un tipus de matriu, com ara struct __jmp_buf_tag[1], adequat per contenir la informació necessària per restaurar un entorn de trucada.

La justificació del C99 descriu jmp_buf com un tipus de matriu per a la compatibilitat enrere ; el codi existent fa referència a les ubicacions d'emmagatzematge jmp_buf pel nom (sense l'operador & address-of), que només és possible per als tipus de matriu.[5]

Exemple d'ús[modifica]

L'exemple següent mostra la idea bàsica de setjmp. Allà, main() crida first(), que al seu torn crida second() . Aleshores, second() torna a saltar a main(), saltant la crida de printf() first() ) .

#include <stdio.h>
#include <setjmp.h>

static jmp_buf buf;

void second() {
    printf("second\n");         // prints
    longjmp(buf,1);             // jumps back to where setjmp was called - making setjmp now return 1
}

void first() {
    second();
    printf("first\n");          // does not print
}

int main() {
    if (!setjmp(buf))
        first();                // when executed, setjmp returned 0
    else                        // when longjmp jumps back, setjmp returns 1
        printf("main\n");       // prints

    return 0;
}

Quan s'executa, el programa anterior sortirà:

second
main

Tingueu en compte que, tot i que es crida la subrutina first(), " first " mai s'imprimeix. " main " s'imprimeix com a instrucció condicional if (!setjmp(buf)) s'executa una segona vegada.

Referències[modifica]

  1. «setjmp - cppreference.com» (en anglès). [Consulta: 19 desembre 2023].
  2. «<csetjmp> (setjmp.h)» (en anglès). [Consulta: 19 desembre 2023].
  3. TylerMSFT. «setjmp» (en anglès americà), 02-12-2022. [Consulta: 19 desembre 2023].
  4. «setjmp(3) - Linux manual page» (en anglès). [Consulta: 19 desembre 2023].
  5. C99 Rationale, version 5.10, April 2003, section 7.13