errors handling

Тема в разделе "LANGS.C", создана пользователем osox, 9 июл 2010.

  1. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    Всех приветствую. вопрос по С
    интересно следующее как правильнее обрабатывать ошибки
    аргументы за тот или иной способ выслушаются с удовольствием

    1
    Код (Text):
    1. retcode ubzd4guwedudy(argtype this)
    2. {
    3.     file_t file;
    4.     thread_t thread;
    5.     map_t map;
    6.  
    7.     file = openfile...
    8.     if (!file)
    9.         return ERROR_FILE_NOT_FOUND;
    10.    
    11.     thread = openthread...
    12.     if (!thread)
    13.     {
    14.         closefile(file);
    15.         return ERROR_ACCESS_DENIED;
    16.     }
    17.  
    18.     map = openmap...
    19.     if (!map)
    20.     {
    21.         closefile(file);
    22.         closethread(thread);
    23.         return ERROR_NOT_ENOUGH_MEMORY;
    24.     }
    25.    
    26.     ...processing...
    27.  
    28.     closefile(file);
    29.     closethread(thread);
    30.     closemap(map);
    31.  
    32.     return ERROR_SUCCESS;
    33. }
    2
    Код (Text):
    1. retcode ubzd4guwedudy(argtype this)
    2. {
    3.     file_t file = NULL;
    4.     thread_t thread = NULL;
    5.     map_t map = NULL;
    6.     retcode retval;
    7.  
    8.     file = openfile...
    9.     if (!file)
    10.     {
    11.         retval = ERROR_FILE_NOT_FOUND;
    12.         goto exit;
    13.     }
    14.    
    15.     thread = openthread...
    16.     if (!thread)
    17.     {
    18.         retval = ERROR_ACCESS_DENIED;
    19.         goto exit;
    20.     }
    21.  
    22.     map = openmap...
    23.     if (!map)
    24.     {
    25.         retval = ERROR_NOT_ENOUGH_MEMORY;
    26.         goto exit;
    27.     }
    28.    
    29.     retval = ERROR_SUCCESS;
    30.    
    31.     ...processing...
    32.  
    33. exit:
    34.  
    35.     if (file)
    36.         closefile(file);
    37.    
    38.     if (thread)
    39.         closethread(thread);
    40.    
    41.     if (map)
    42.         closemap(map);
    43.  
    44.     return retval;
    45. }
    3
    Код (Text):
    1. retcode ubzd4guwedudy(argtype this)
    2. {
    3.     file_t file;
    4.     thread_t thread;
    5.     map_t map;
    6.     retcode retval;
    7.  
    8.     file = openfile...
    9.     if (file)
    10.     {
    11.         thread = openthread...
    12.         if (thread)
    13.         {
    14.             map = openmap...
    15.             if (map)
    16.             {
    17.                 retval = ERROR_SUCCESS;
    18.                 ...processing...
    19.                 closemap(map);
    20.             }
    21.             else
    22.                 retval = ERROR_NOT_ENOUGH_MEMORY;
    23.            
    24.             closethread(thread);
    25.         }
    26.         else
    27.             retval = ERROR_ACCESS_DENIED;
    28.        
    29.         closefile(file);
    30.      }
    31.      else
    32.          retval = ERROR_FILE_NOT_FOUND;
    33.    
    34.  
    35.     return retval;
    36. }
    4
    Код (Text):
    1. retcode ubzd4guwedudy(argtype this)
    2. {
    3.     file_t file = NULL;
    4.     thread_t thread = NULL;
    5.     map_t map = NULL;
    6.     retcode retval;
    7.  
    8.     __try
    9.     {
    10.         file = openfile...
    11.         if (!file)
    12.         {
    13.             retval = ERROR_FILE_NOT_FOUND;
    14.             __leave;
    15.         }
    16.          
    17.         thread = openthread...
    18.         if (!thread)
    19.         {
    20.             retval = ERROR_ACCESS_DENIED;
    21.             __leave;
    22.         }
    23.  
    24.         map = openmap...
    25.         if (!map)
    26.         {
    27.             retval = ERROR_NOT_ENOUGH_MEMORY;
    28.             __leave;
    29.         }
    30.        
    31.         retval = ERROR_SUCCESS;
    32.        
    33.         ...processing...
    34.     }
    35.    
    36.     __finally
    37.     {
    38.         if (file)
    39.             closefile(file);
    40.        
    41.         if (thread)
    42.             closethread(thread);
    43.        
    44.         if (map)
    45.             closemap(map);
    46.     }
    47.  
    48.     return retval;
    49. }
     
  2. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    osox
    за номер 2 руки отрывают
    номер 4 это не си
    а остальное навыбор)
     
  3. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    у меня имхо такое если 4 - ое не рассаматривать
    из за того что пишется что то кросплатформенное тогда
    остается 1 - ое 2 - ое и 3 - е дальше 1 - ое
    тоже можно не рассматривать кому захочется копипастить код
    пачками тогда остается только goto или много
    вложенных if'ов я очень не люблю много вложенных if'ов
    из за того что код начинает выезжать за правый край страницы
    поэтому я бы выбрал именно 2

    можно ответить разбей функцию на две и не будет
    много вложенных if'ов но зачем ее разбивать если это логически
    законченная единица не требующая разбиения только для того
    что бы не пользоватся goto ? или смирится с тем что
    часть кода по мере вложения if'ов уедет за правый край страницы ?
     
  4. fsd

    fsd New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    353
    можно так
    Код (Text):
    1. retcode ret = ERROR_SUCCESS;
    2.  
    3. do
    4. {
    5.     if(...)
    6.     {
    7.          ret = ...;
    8.          break;
    9.     }
    10.  
    11.     //...
    12.  
    13.  
    14.     if(...)
    15.     {
    16.          ret = ...;
    17.          break;
    18.     }
    19.  
    20.     //...
    21.  
    22. }while(0);
    23.  
    24. if(ret != ERROR_SUCCESS)
    25. {
    26.     //...
    27. }
    28.  
    29. return ret;
     
  5. Noga

    Noga New Member

    Публикаций:
    0
    Регистрация:
    10 окт 2008
    Сообщения:
    92
    wsd

    Из-за goto? Помнится в прошлом году был семинар для разработчиков от HP, так вот там они говорили что goto - хорошо и он полезен.
     
  6. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Noga
    ога
    "Остапа понесло" ))
     
  7. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    здоровый jmp вне закона?
    господа, будьте честны с собой,
    когда вы говорите такие вещи, вам не становится немножко стыдно, или грустно, или забавно?
     
  8. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    goto cleanup - это идиома
     
  9. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    Com[e]r
    ничего смешного, в ООП коде это сильно напрягает
    в асме да, без него ни как
     
  10. wf_

    wf_ New Member

    Публикаций:
    0
    Регистрация:
    18 окт 2009
    Сообщения:
    40
    Интересно, чем это умеренное использование goto всех напрягает, подобная схема (2) в ядре линукса много где юзается...
    Уж лучше goto чем лесенки с 12-ю уровнями вложенности...
     
  11. google

    google New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2007
    Сообщения:
    140
    Да и не только в линуксе, посмотрите любой пример из MSDN с использованием COM-интерфейсов. Одни goto.
     
  12. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    goto зло в ЯВУ
     
  13. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    если каком-то ЯВУ нет адекватной замены goto, остается использовать goto

    конечно RAII + эксепшены лучше, только в Си этого нет
     
  14. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    wf_
    это ядро ни когда не было и не будет расшарено, потому что у создателя не излечимая
    ПАРАНОЯ, что везде одни недоброжелатели и доверять можно только себе))) может это
    патология, но кой где видел мнения что это национальные особенности ((
    так что это вопрос к его единоличному архитектору
    GoldFinch
    скажи это Кенту Бекку и запости ответ)
     
  15. google

    google New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2007
    Сообщения:
    140
    Кому не нравятся goto, можно использовать макросы:
    Код (Text):
    1. #include "stdafx.h"
    2. #include "Epvolume.h"
    3.  
    4. HWND g_hDlg = NULL;
    5. GUID g_guidMyContext = GUID_NULL;
    6.  
    7. static IAudioEndpointVolume *g_pEndptVol = NULL;
    8. static BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM);
    9.  
    10. #define EXIT_ON_ERROR(hr)  \
    11.               if (FAILED(hr)) { goto Exit; }
    12. #define ERROR_CANCEL(hr)  \
    13.               if (FAILED(hr)) {  \
    14.                   MessageBox(hDlg, TEXT("The program will exit."),  \
    15.                              TEXT("Fatal error"), MB_OK);  \
    16.                   EndDialog(hDlg, TRUE); return TRUE; }
    17.  
    18. //-----------------------------------------------------------
    19. // WinMain -- Registers an IAudioEndpointVolumeCallback
    20. //   interface to monitor endpoint volume level, and opens
    21. //   a dialog box that displays a volume control that will
    22. //   mirror the endpoint volume control in SndVol.
    23. //-----------------------------------------------------------
    24. int APIENTRY WinMain(HINSTANCE hInstance,
    25.                      HINSTANCE hPrevInstance,
    26.                      LPSTR lpCmdLine,
    27.                      int nCmdShow)
    28. {
    29.     HRESULT hr = S_OK;
    30.     IMMDeviceEnumerator *pEnumerator = NULL;
    31.     IMMDevice *pDevice = NULL;
    32.     CAudioEndpointVolumeCallback EPVolEvents;
    33.  
    34.     if (hPrevInstance)
    35.     {
    36.         return 0;
    37.     }
    38.  
    39.     CoInitialize(NULL);
    40.  
    41.     hr = CoCreateGuid(&g_guidMyContext);
    42.     EXIT_ON_ERROR(hr)
    43.  
    44.     // Get enumerator for audio endpoint devices.
    45.     hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
    46.                           NULL, CLSCTX_INPROC_SERVER,
    47.                           __uuidof(IMMDeviceEnumerator),
    48.                           (void**)&pEnumerator);
    49.     EXIT_ON_ERROR(hr)
    50.  
    51.     // Get default audio-rendering device.
    52.     hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
    53.     EXIT_ON_ERROR(hr)
    54.  
    55.     hr = pDevice->Activate(__uuidof(IAudioEndpointVolume),
    56.                            CLSCTX_ALL, NULL, (void**)&g_pEndptVol);
    57.     EXIT_ON_ERROR(hr)
    58.  
    59.     hr = g_pEndptVol->RegisterControlChangeNotify(
    60.                      (IAudioEndpointVolumeCallback*)&EPVolEvents);
    61.     EXIT_ON_ERROR(hr)
    62.  
    63.     InitCommonControls();
    64.     DialogBox(hInstance, L"VOLUMECONTROL", NULL, (DLGPROC)DlgProc);
    65.  
    66. Exit:
    67.     if (FAILED(hr))
    68.     {
    69.         MessageBox(NULL, TEXT("This program requires Windows Vista."),
    70.                    TEXT("Error termination"), MB_OK);
    71.     }
    72.     if (pEnumerator != NULL)
    73.     {
    74.         g_pEndptVol->UnregisterControlChangeNotify(
    75.                     (IAudioEndpointVolumeCallback*)&EPVolEvents);
    76.     }
    77.     SAFE_RELEASE(pEnumerator)
    78.     SAFE_RELEASE(pDevice)
    79.     SAFE_RELEASE(g_pEndptVol)
    80.     CoUninitialize();
    81.     return 0;
    82. }
    83.  
    84. //-----------------------------------------------------------
    85. // DlgProc -- Dialog box procedure
    86. //-----------------------------------------------------------
    87.  
    88. BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    89. {
    90.     HRESULT hr;
    91.     BOOL bMute;
    92.     float fVolume;
    93.     int nVolume;
    94.     int nChecked;
    95.  
    96.     switch (message)
    97.     {
    98.     case WM_INITDIALOG:
    99.         g_hDlg = hDlg;
    100.         SendDlgItemMessage(hDlg, IDC_SLIDER_VOLUME, TBM_SETRANGEMIN, FALSE, 0);
    101.         SendDlgItemMessage(hDlg, IDC_SLIDER_VOLUME, TBM_SETRANGEMAX, FALSE, MAX_VOL);
    102.         hr = g_pEndptVol->GetMute(&bMute);
    103.         ERROR_CANCEL(hr)
    104.         SendDlgItemMessage(hDlg, IDC_CHECK_MUTE, BM_SETCHECK,
    105.                            bMute ? BST_CHECKED : BST_UNCHECKED, 0);
    106.         hr = g_pEndptVol->GetMasterVolumeLevelScalar(&fVolume);
    107.         ERROR_CANCEL(hr)
    108.         nVolume = (int)(MAX_VOL*fVolume + 0.5);
    109.         SendDlgItemMessage(hDlg, IDC_SLIDER_VOLUME, TBM_SETPOS, TRUE, nVolume);
    110.         return TRUE;
    111.  
    112.     case WM_HSCROLL:
    113.         switch (LOWORD(wParam))
    114.         {
    115.         case SB_THUMBPOSITION:
    116.         case SB_THUMBTRACK:
    117.         case SB_LINERIGHT:
    118.         case SB_LINELEFT:
    119.         case SB_PAGERIGHT:
    120.         case SB_PAGELEFT:
    121.         case SB_RIGHT:
    122.         case SB_LEFT:
    123.             // The user moved the volume slider in the dialog box.
    124.             SendDlgItemMessage(hDlg, IDC_CHECK_MUTE, BM_SETCHECK, BST_UNCHECKED, 0);
    125.             hr = g_pEndptVol->SetMute(FALSE, &g_guidMyContext);
    126.             ERROR_CANCEL(hr)
    127.             nVolume = SendDlgItemMessage(hDlg, IDC_SLIDER_VOLUME, TBM_GETPOS, 0, 0);
    128.             fVolume = (float)nVolume/MAX_VOL;
    129.             hr = g_pEndptVol->SetMasterVolumeLevelScalar(fVolume, &g_guidMyContext);
    130.             ERROR_CANCEL(hr)
    131.             return TRUE;
    132.         }
    133.         break;
    134.  
    135.     case WM_COMMAND:
    136.         switch ((int)LOWORD(wParam))
    137.         {
    138.         case IDC_CHECK_MUTE:
    139.             // The user selected the Mute check box in the dialog box.
    140.             nChecked = SendDlgItemMessage(hDlg, IDC_CHECK_MUTE, BM_GETCHECK, 0, 0);
    141.             bMute = (BST_CHECKED == nChecked);
    142.             hr = g_pEndptVol->SetMute(bMute, &g_guidMyContext);
    143.             ERROR_CANCEL(hr)
    144.             return TRUE;
    145.         case IDCANCEL:
    146.             EndDialog(hDlg, TRUE);
    147.             return TRUE;
    148.         }
    149.         break;
    150.     }
    151.     return FALSE;
    152. }
     
  16. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    нормальные люди на Си не пишут %)
    а пишут как минимум на С++, и то редко
     
  17. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    google :derisive:)
    Код (Text):
    1. #define FINALLY_ON_TRUE(expr, retvalue) \
    2.     do { if (expr) { retval = retvalue; __leave; } } while (0)
    3.  
    4. retcode ubzd4guwedudy(argtype this)
    5. {
    6.     file_t file = NULL;
    7.     thread_t thread = NULL;
    8.     map_t map = NULL;
    9.     retcode retval;
    10.  
    11.     __try
    12.     {
    13.         file = openfile...
    14.         FINALLY_ON_TRUE(!file, ERROR_FILE_NOT_FOUND);
    15.  
    16.          
    17.         thread = openthread...
    18.         FINALLY_ON_TRUE(!thread, ERROR_ACCESS_DENIED);
    19.        
    20.  
    21.         map = openmap...
    22.         FINALLY_ON_TRUE(!map, ERROR_NOT_ENOUGH_MEMORY);
    23.        
    24.                
    25.         retval = ERROR_SUCCESS;
    26.        
    27.         ...processing...
    28.     }
    29.    
    30.     __finally
    31.     {
    32.         if (file)
    33.             closefile(file);
    34.        
    35.         if (thread)
    36.             closethread(thread);
    37.        
    38.         if (map)
    39.             closemap(map);
    40.     }
    41.  
    42.     return retval;
    43. }
     
  18. friackazoid

    friackazoid New Member

    Публикаций:
    0
    Регистрация:
    4 июн 2009
    Сообщения:
    102
    Товариши, что с вами? Зачем так отрыватся от корней?

    Код (Text):
    1.      if(!(file=openfile)) {
    2.           retVal = ERROR_FILE_NOT_FOUND;
    3.           goto out;
    4.      }
    5.  
    6.      if (!(map=openmap)) {
    7.           retVal = ERROR_ACCESS_DENIDED;
    8.           goto free_file;
    9.      }
    10.  
    11. free_file:
    12.      close(file)
    13. out:
    14.      return;
     
  19. osox

    osox New Member

    Публикаций:
    0
    Регистрация:
    13 ноя 2009
    Сообщения:
    280
    GoldFinch
    это C++ так развращает ?)))
     
  20. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    GoldFinch
    А на чем часто?
    На жабе или 1С ?