Domanda

Se posto atexit( fn ); sullo stack di uscita, verrà eseguito all'uscita del programma:ritorna da main() o tramite exit().

Posso rimuoverlo dallo stack?

Perché voglio farlo, chiedi?

Stavo sperimentando un semplice meccanismo try-catch utilizzando atexit, setjmp E longjmp.Sarebbe semplicemente perfetto se potessi undo-atexit(fn); - anche se funzionerebbe solo per l'ultima funzione registrata.

Modificare:

Seguendo il suggerimento di Monoceres di creare il mio stack...

Per ora lo stack funziona solo con un raccoglitore di eccezioni.

void (*_catchFn[10])()  = {0,0,0,0,0,0,0,0,0,0};

void _catch(){
  if ( _catchFn[0] != 0 ){
    (_catchFn[0])();
  }
}

void _addCatch( void (*fn)() ){
  _catchFn[0]=fn;
}

void _remCatch( void (*fn)() ){
  _catchFn[0]=0;
}

void test(){
  jmp_buf env;

  void catch(){                  // we get here after an exit with a registered catch
    longjmp(env,1);              // return to the line marked except...
                               //   that first will get the value 1
  }
  int first = setjmp( env);      // ** return here **
  fprintf( stderr , "test: After setjmp. first=%d\n" , first );
  if( first == 0 ){              // try this code
    _addCatch(catch);            // register the catch function to 'catch' the exit
    fprintf( stderr , "test: Before CHECK\n" );
    // CHECK something and something bad happens and it exits
    exit(1);                     // like this
    fprintf( stderr , "test: After CHECK - THIS SHOULD NEVER BE SEEN AFTER AN EXCEPTION.\n" );
  }else{
    fprintf( stderr , "test: After longjmp return. first=%d\n" , first );
  }
  _remCatch( catch);
  fprintf( stderr , "test: IT WORKED!\n");
  exit(1);  // exit again to see if we are safe
}

int main(){
  atexit( _catch );              // register my global exception stack
  test();
}
È stato utile?

Soluzione

Perché non creare il tuo stack che chiami da una singola funzione atexit()?In questo modo puoi manipolare lo stack quanto vuoi.

Altri suggerimenti

No, non puoi farlo, ma puoi usare il flag globale in modo che il tuo gestore di uscita non faccia nulla se il flag è impostato.

In alternativa puoi chiamare _Exit() (C99) - eseguirà la normale procedura di uscita (chiuderà tutti i descrittori aperti, invierà tutti i segnali necessari e genitore/figlio) ma non chiamerà il gestore di uscita.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top