Re[2]: Обработка ошибок и корректный выход
От: MBy Украина http://maxim.vuets.name/
Дата: 03.07.06 18:52
Оценка:
Здравствуйте, Какая разница, Вы писали:

КР>Еще есть вариант посмотреть в сторону функции atexit


КР>
КР>Processes the specified function at exit.

КР>int atexit( void ( __cdecl *func )( void ) );
КР>


КР>Если открытые файлы хранить в каком то списке и иметь глобальный указатель на этот список то

КР>имхо тогда легко в этой функцими произвести корректное закрытие всех открытых файлов

И такая мысль была. Пока отказался по причине простоты приложения.
Hoc est simplicissimum!
Re[3]: Обработка ошибок и корректный выход
От: _Storm  
Дата: 07.07.06 07:11
Оценка: 1 (1) :)
Здравствуйте, MBy, Вы писали:

MBy>Типа так?

MBy>
MBy>/* ... */
MBy>  SOME_HANDLE handle = NULL;
MBy>  char* str = NULL;

MBy>  if( some_constructor( &handle ) )
MBy>    goto the_end;

MBy>  str = calloc( 16, sizeof(char) );
MBy>  if( str == NULL )
MBy>    goto the_end;

MBy>  if( some_func( handle, str ) )
MBy>    goto the_end;

MBy>the_end:
MBy>  if( handle )
MBy>    some_destructor( handle );
MBy>  if( str )
MBy>    free( str );

MBy>  return;

MBy>/* ... */
MBy>


MBy>Или я не в ту сторону думаю?

MBy>Правда, тут бы ещё коды ошибок добавить для пущей красоты. Ну или хотя бы true/false.

Я бы переписал это так (без goto)

/* ... */
SOME_HANDLE handle = NULL;
char* str = NULL;

do
{
    if( some_constructor( &handle ) )
        break;

    str = calloc( 16, sizeof(char) );
    if( str == NULL )
        break;

    if( some_func( handle, str ) )
        break;
        
} while(false);

if( handle )
    some_destructor( handle );
if( str )
    free( str );

return;

/* ... */
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Обработка ошибок и корректный выход
От: MBy Украина http://maxim.vuets.name/
Дата: 07.07.06 07:45
Оценка: +1
Здравствуйте, _Storm, Вы писали:

_S>Я бы переписал это так (без goto)


_S>
_S>} while(false);
_S>


Ну точнее, while(0). Дык ведь Си
А в целом понятно. Спасибо. Посмотрим, может кто-то другой вариант предложит
Hoc est simplicissimum!
Re: Обработка ошибок и корректный выход
От: Dair Россия  
Дата: 07.07.06 08:17
Оценка:
Ещё один вариант:


#define FUNCTION_NUM (5)

int do_something1( void )
{
  ...

  if( all_ok )
    return 1;
  else {
    fprintf( stderr, "Error bla-bla-bla\n" );
    return 0;
  }
}

int do_something2( void )
{
  ...
}

...

int do_something5( void )

...

typedef int (*action)();

int main( void )
{
  int ret = 0;

  action handler[FUNCTION_NUM] = { do_something1, do_something2, ..., do_something5 };

  open_files();

  for( int i = 0; i < FUNCTION_NUM; ++i ) {
    if( ! handler[i]() ) {
      ret = 1;
      break;
    }
  }

  close_files();
  
  return ret;
}


Если функции совсем независимы друг от друга, можно break в цикле не делать.
Re[4]: Обработка ошибок и корректный выход
От: Erop Россия  
Дата: 07.07.06 12:43
Оценка:
Здравствуйте, _Storm, Вы писали:

_S>Я бы переписал это так (без goto)


_S>
_S>do
_S>{
...
_S>} while(false);
_S>



Я правильно понимаю, что do { ... } while( false ); добавлено типа для повышения читабельности?
Или какой такой смысл изводить goto в этом месте таким образом?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Обработка ошибок и корректный выход
От: _Storm  
Дата: 07.07.06 12:59
Оценка: -1 :)
Здравствуйте, Erop, Вы писали:

E>Я правильно понимаю, что do { ... } while( false ); добавлено типа для повышения читабельности?

E>Или какой такой смысл изводить goto в этом месте таким образом?

Правильно, читабельности, а вследствие и уменьшения возможности допустить ошибку в cлучае goto т.к. метку можно случайно не в то место поставить, передвинуть, а вот со скобками уже тяжелее ошибиться, плюс нагляднее смотрится. Эту конструкцию do {...} while(false) уже где-то на рсдн обсуждали.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Обработка ошибок и корректный выход
От: MaximE Великобритания  
Дата: 08.07.06 10:28
Оценка:
MBy wrote:

> Пишу на Си. Например, некая ф-ия не смогла что-то выполнить и вернула

> ошибку. Продолжение выполнения программы стало безсмысленным. Как в
> таком случае правильнее всего обработать эту ошибку и выйти из
> программы?

exit() или abort(). abort() создаст core file, из которого ты можешь попытаться
узнать, что пошло не так.

> При том следует учесть, что необходимо закрыть n-ое

> количество файлов и вернуть в кучу выделиную память, то есть сделать не
> выброс а корректное завершение.

Все ресурсы будут закрыты за тебя операционной системой, кроме ресурсов с kernel
и filesystem persistency. Ресурсы с kernel persistency на linux: semaphore,
shared memory, message queue; с filesystem: файлы и тому подобное (named pipe,
device nodes, ...).

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 2.0
Re[3]: Обработка ошибок и корректный выход
От: mr_jek  
Дата: 14.07.06 14:31
Оценка:
Здравствуйте, MBy, Вы писали:

MBy>Типа так?

MBy>
MBy>/* ... */
MBy>  SOME_HANDLE handle = NULL;
MBy>  char* str = NULL;

MBy>  if( some_constructor( &handle ) )
MBy>    goto the_end;

MBy>  str = calloc( 16, sizeof(char) );
MBy>  if( str == NULL )
MBy>    goto the_end;

MBy>  if( some_func( handle, str ) )
MBy>    goto the_end;

MBy>the_end:
MBy>  if( handle )
MBy>    some_destructor( handle );
MBy>  if( str )
MBy>    free( str );

MBy>  return;

MBy>/* ... */
MBy>


я думаю так будет проще и понятнее:

  int err = 0;
  char* str = NULL;
  
  err = some_constructor(&handle);
  if (err)     
    goto out_construct_failed;

  str = calloc( 16, sizeof(char) );
  if (!str) {
    err = ENOMEM;
    goto out_mermory;
  }
  err = some_func(handle, str);
  if (err)
    goto out_some_func_failed;

  err = 0;

out_some_func_failed:
    free(str);
out_memory:
  some_destructor( handle )
out_construct_failed:
  return err;
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.