Вопрос

Если я размещу atexit( fn ); в стеке выхода он будет выполнен при завершении программы:возвращается из main() или через exit().

Могу ли я удалить его из стека?

Почему я хочу это сделать, спросите вы?

Я экспериментировал с простым механизмом try-catch, используя atexit, setjmp и longjmp.Это было бы просто идеально, если бы я мог undo-atexit(fn); - даже если это будет работать только для последней зарегистрированной функции.

Редактировать:

Следуя предложению monoceres создать свой собственный стек...

На данный момент стек работает только с одним средством улавливания исключений.

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();
}
Это было полезно?

Решение

Почему бы не создать свой собственный стек, который вы вызываете из одной функции atexit()?Таким образом, вы могли бы манипулировать стеком сколько угодно.

Другие советы

Нет, вы не можете этого сделать, но вы можете использовать глобальный флаг, чтобы ваш обработчик выхода ничего не делал, если флаг установлен.

В качестве альтернативы вы можете позвонить _Exit() (C99) - он выполнит обычную процедуру выхода (закроет все открытые дескрипторы, отправит все необходимые сигналы и родительские / дочерние элементы), но не вызовет обработчик выхода.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top