2011-09-01 8 views
9

Programmazione Avanzata in UNIX Environment di W. Richard Stevens afferma:Che cos'è una variabile automatica in questo contesto setjmp/longjmp?

"Quali sono gli stati delle variabili automatiche e registrano variabili nella funzione principale?"

in relazione a ciò che accade quando si esegue il longjmp su main (o un'altra funzione) da qualche parte più in basso nella pila.

E continua dicendo:

"Dipende maggior parte delle implementazioni non cercano di ripristinare questi variabili automatiche e registrare le variabili, ma tutto ciò che gli standard dire è che i loro valori sono indeterminati.. Se si dispone di un variabile automatica che non si desidera rollback, definirlo con l'attributo volatile. variabili dichiarate globale o statica sono lasciati soli quando longjmp viene eseguito.

Sembra che stia dicendo che le normali variabili stack non avranno i loro valori impostati su ciò che erano al momento del setjmp - ma poi il resto della funzione non poteva contare sulle sue variabili stack dopo il longjmp indietro ad esso che sembra pazzo, quindi immagino di sbagliarmi.

Qualcuno può definire "variabili automatiche" per me e spiegare cosa specificamente non è impostato sul valore originale e perché lo è?

+1

Una variabile automatica è semplicemente una con la classe di memoria 'auto', che è l'impostazione predefinita sulle variabili di funzione che non hanno altre dichiarazioni di classi di memoria. È una parola chiave, lo sai. – tchrist

risposta

6

Tutto quello che sta dicendo è che se

  1. voi hanno una variabile automatica (funzione-locale non statico) che non viene dichiarato volatile; e
  2. si modifica il valore della variabile tra il setjmp e longjmp

poi dopo la longjmp il valore di tale variabile diventa indeterminato.

Credo che questo abbia a che fare con la possibilità che tali variabili risiedano nei registri della CPU piuttosto che nella RAM e la difficoltà associata di preservare i valori di tale variabile attraverso lo longjmp.

Ecco una citazione dal gcc manual:

Se si utilizza longjmp, attenzione alle variabili automatiche. ISO C dice che le variabili automatiche non dichiarate volatile hanno valori non definiti dopo un longjmp. E questo è tutto ciò che GCC promette di fare, perché è molto difficile ripristinare correttamente le variabili di registro, e una delle funzionalità di GCC è che può mettere le variabili nei registri senza come richiesto.

Se la potenziale perdita di valori variabili è un problema nel proprio caso d'uso, dichiarare le variabili rilevanti come volatile.

+3

Ovviamente, la citazione manuale di gcc è una spiegazione sbagliata: non è in realtà ciò che dice ISO C. Rende solo indefinito _se sono modificati_, e ciò che è difficile non è ripristinarli (dopotutto, puoi solo salvare e ripristinare TUTTI i registri) ma _avoidare_ ripristini indesiderati. – Random832

+0

Infatti, il * motivo * per questo UB è che è facile salvare tutti i valori del registro e ripristinarli, ma non è pratico per l'implementazione tenere traccia di * quale copia del valore * (quello in memoria o quello memorizzato nella cache in un registro) era il più aggiornato al momento del 'longjmp'. –

+0

@ Random832: Grazie - Ho modificato la risposta nel tentativo di chiarire ulteriormente le cose. – NPE

0

Le variabili automatiche sono variabili locali di funzione - poiché sono allocate nello stack e non è necessario preoccuparsi della loro memoria, esse vengono chiamate automatica.

Vedere http://en.wikipedia.org/wiki/Automatic_variable per una descrizione più approfondita.

6

"Variabili automatiche" è un termine vecchio per variabili locali ordinarie (non dichiarate con registro o statiche), che risale alla terminologia utilizzata nello standard C e al significato originale della parola chiave auto. Vedi le sezioni 6.2.4 e 6.7.1 della the standard

Per quanto riguarda questo:

ma poi il resto della funzione non potevano contare sulle sue variabili di stack dopo il longjmp di nuovo esso che sembra folle

L'idea è che non dovresti modificarli in primo luogo se stai andando a longjmp perché non puoi sapere cosa succederà.

Il ragione è che longjmp può ripristinare lo stato come registri del processore, che variabili automatiche possono essere stati mappati (non v'è alcuna garanzia che saranno in "stack" o in memoria a tutti. E anche se esistono in memoria, alcune operazioni potrebbero non [a meno che non sia dichiarato volatile] accedere direttamente alla memoria ma possono accedere a un registro del processore in cui il valore è già stato caricato)

La tua domanda è un po 'strana perché ti implica vogliono da ripristinare [vale a dire le tue modifiche nelle funzioni intervenienti da cancellare] - in generale questa avvertenza avverte che potrebbero essere ripristinate da incidente quando non è previsto. "Non ripristinato" non significa "inutilizzabile" [anche se lo standard DOES li dichiara inutilizzabili perché potrebbe ripristinare un registro memorizzato nella cache ma non la memoria in modo da ottenere risultati incoerenti], significa "ha il valore di una funzione successiva scritta in it (perché hai passato l'indirizzo che intendeva scrivere su) ".

+0

È strano che così tante persone oggi sembrano aver dimenticato le quattro quattro [parole chiave della classe di archiviazione] di C (http://en.wikipedia.org/wiki/Static_variable) per le loro variabili: 'auto',' static', 'register' e 'extern' - sebbene una variabile' volatile' sia [qualcosa di diverso] (http://en.wikipedia.org/wiki/Volatile_variable), e alquanto dubbiosa. – tchrist

0

auto significa tutto ciò che è locale per la funzione e non è stato definito in modo specifico come static. E 'probabilmente la pena notare che la norma specifica più o meno il comportamento egli afferma (§7.13.2/3):

Tutti gli oggetti accessibili hanno valori, e tutti gli altri componenti della macchina astratta avere stato, come del è stata richiamata la funzione longjmp, tranne i valori degli oggetti di durata della memorizzazione automatica locali alla funzione contenente la chiamata della macro setjmp corrispondente che non ha il tipo qualificato volatile e sono stati modificati tra l'invocazione setjmp e la chiamata longjmp è indeterminata.

0

non posso definire una "variabile automatico", ma forse che può aiutare a capire che cosa succede durante una setjump:

(alcuni dei) CPU registri e salvato in un file.

e durante longjump:

il valore dei registri della CPU viene riportato al valore salvato.

nient'altro! (here è un esempio)

Così durante la longjump, è appena tornato più alto nella pila, con tutte le variabili salvate nella memoria intatta, e alcuni (non tutti) dei registri, in particolare il stack pointer e il instruction pointer ripristinati al valore che avevano durante il setjmp.

Problemi correlati