кошерный код на Си под Windows

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Gar|k, 14 May 2011.

  1. Gar|k

    Gar|k Moderator

    Joined:
    20 Mar 2009
    Messages:
    1,166
    Likes Received:
    266
    Reputations:
    82
    В примерах кода от мелкософта встречается такое

    Code:
    if ( NULL == lpvReserved )
                {
                    if ( 0xFFFFFFFF != gTlsIndex )
                    {
                        TlsFree( gTlsIndex );
                        gTlsIndex = 0xFFFFFFFF;
                    }
                }
    
    Code:
    int ...(...) 
    {
    INT        ret = SOCKET_ERROR;
        //
        // Make sure the window handle is valid
        //
        ret = SOCKET_ERROR;
        if ( FALSE == IsWindow( hWnd ) )
        {
            goto cleanup;
        }
    
    cleanup:
        return ret;
    }
    
    Чем отличается NULL == lpvReserved, от lpvReserved == NULL ?
    почему goto ? почему бы не return SOCKET_ERROR; ?

    встречаеться и такое
    Code:
    BOOL ...(...)
    {
    BOOL ret=FASLE;
    
    ret=FASLE;
    if(...) ret=TRUE;
    return ret;
    }
    
    зачем вводить переменную для результата? (помню SLESH говорил что ему кто-то объяснял разницу)

    Я думаю нужно посмотреть выходной асм листинг, чтобы понять, влияет ли это на код и его логику или это просто замороты прогеров мелкософта...
     
    _________________________
    #1 Gar|k, 14 May 2011
    Last edited: 14 May 2011
  2. ЕгоАкк

    ЕгоАкк Banned

    Joined:
    21 Sep 2009
    Messages:
    84
    Likes Received:
    18
    Reputations:
    0
    >Чем отличается NULL == lpvReserved, от lpvReserved == NULL ?
    Чтобы случайно не написать присвоение lpvReserved null.

    >почему goto ? почему бы не return SOCKET_ERROR; ?
    Это обработка ошибок при помощи goto, просто пример не полный.
    http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/

    >зачем вводить переменную для результата?
    Опять пример не полный, смысл в том, чтобы не писать для каждого if else а пройти их сразу в случае чего поменять возвращаемое значение.
     
    1 person likes this.
  3. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    честно говоря в сях не силен (делфи-говнокодер), но даж я применяю reult:='OK' или че-то в этом духе,
    т.е. как-то так
    Code:
    BOOL ...(...)
    {
    BOOL result=FASLE;
    
    if(...) result=TRUE;
    return result;
    }
     
  4. patcher

    patcher Banned

    Joined:
    15 Dec 2009
    Messages:
    190
    Likes Received:
    37
    Reputations:
    10
    то что в Delphi
    Code:
    result:='OK'
    на сях и есть
    Code:
    return "OK"
     
  5. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,705
    Likes Received:
    1,225
    Reputations:
    455
    1) есть как бы логика алгоритмизации - процедура / функция должна иметь одну точку входа и желательно только одну точку выхода (что бы не было непонятных ветвлений)
    По этому и юзают промежуточную переменную. К томуже компилятору проще когда одна точка выхода т.к. в ней он почистит стек, доделает кучу всего в плане проверки переполнения буфера. В С++ вообще там происходил уничтожение локальных классов.

    2) NULL == lpvReserved звучит как-то в стиле синее == море
    но вообще разницы особо нет. но как уже выше сказано чтобы случайно не присвоить значение, хотя компилятор выдаст ошибку скорее всего (хотя может и не выдать)

    3) Часто вообще люди вместо goto делают циклы. типа
    do
    {
    if ** then break;
    if ** then break;
    if ** then break;
    if ** then break;
    } while (false);

    как бы быстрых переход к месте но без goto. Изврат но всёже часто используют нелюбители goto
     
  6. Ins3t

    Ins3t Харьковчанин

    Joined:
    18 Jul 2009
    Messages:
    942
    Likes Received:
    428
    Reputations:
    139
    в данном примере готу вообще не в тему, а вот если между условием и cleanup: должен быть еще какой то код - тогда вполне логично.

    и то, что эти примеры со страниц микрософта - не означает, что этот код хорош.
     
  7. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,705
    Likes Received:
    1,225
    Reputations:
    455
    Простой пример:
    создали 3 сокета, 2 события, и выделили память. И тут вдруг какая-то ошибка у тебя, просто сделать return не ты имеешь права, потому что не подчистил за собой
     
  8. Nesar

    Nesar New Member

    Joined:
    20 Apr 2011
    Messages:
    2
    Likes Received:
    0
    Reputations:
    0
    Дизассемблируйте goto -- это быстрй jmp на код в гото ничего страшного нет
     
  9. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    я конечно не знаю, но когда у нас в универе было программирование на паскале (аж 1 семестр), то преподаватели негативно относились к goto, а тех, кто учился на программеров вообще линейкой по пальцам били за "goto" в коде.
     
  10. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    724
    Likes Received:
    110
    Reputations:
    22
    Негативно относились, а причину тебе забыли объяснить? Дело далеко не в производительности.
     
  11. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    Честно говоря причины не помнб, врать не буду, но я даже и не думал что в производительности.
     
  12. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,705
    Likes Received:
    1,225
    Reputations:
    455
    причина негатива к goto только в читабельности кода и возможности случайно допустить ошибку в плане не освобождения ресурсов. но порой бывают очень сложные вещи которые без goto выгледят отвратительно.
     
  13. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    часто goto можно увидеть в такой роли
    Code:
    ...f()
    {
    	keypad_t kpad = invalid_value;
    	pointer someptr = null;
    	context_t ctx = invalid_value;
    
    	error_code_t res;
    
    	res = do_something1(&kpad);
    	if (nt_error(res))
    	{
    		g_warn_if_reached();
    		goto quit;
    	}
    	...
    	someptr = do_something2();
    	if (!someptr)
    	{
    		g_warn_if_reached();
    		res = not_enough_mem;
    		goto quit;
    	}
    	...
    	res = do_something3(&ctx);
    	if (nt_error(res))
    	{
    		g_warn_if_reached();
    		goto quit;
    	}
    
    	... do more work
    
    	res = status_success;
    
    quit:
    	if (invalid_value != kpad)
    		deallocate1(kpad);
    	if (someptr && status_success != res)
    		deallocate2(someptr);
    	if (invalid_value != ctx)
    		deallocate3(ctx);
    	return res;
    }
    
     
  14. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,705
    Likes Received:
    1,225
    Reputations:
    455
    greki_hoy правильно привел код. там goto используется для того, чтобы избежать большой вложенности. А разбивать такой код на более мелкий нецелесообразно.

    Или подобный код когда используются критические секции и прочие вещи с большой вложенностью, тогда вообще отдельные функции будут вызывать трудности
     
    1 person likes this.
Loading...