Re[2]: Проверка условий и "ширина" кода
От: CreatorCray  
Дата: 28.04.08 10:52
Оценка: 1 (1) +4 -2
Здравствуйте, andrey.desman, Вы писали:

AD>
AD>bool func1
AD>{
AD>    return condition1 && (do1(), true) &&
AD>           condition2 && (do2(), true) && 
AD>           condition3 && (do3(), true) &&
AD>           condition4 && (do4(), true);
AD>}
AD>

Читабельность еще хуже чем у первых двух ИМХО
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re: Проверка условий и "ширина" кода
От: jazzer Россия Skype: enerjazzer
Дата: 28.04.08 07:46
Оценка: 24 (1) +5
Здравствуйте, AlexKr, Вы писали:

AK>Добрый день.


AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.


Это — давнее суеверие, что в функции должно быть только одно место для выхода (single return).

Оно частично имеет смысл для С (освобождение ресурсов перед выходом), но для С++, очевидно, оно абсурдно, потому что исключение может вылететь практически из любой строчки.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Проверка условий и "ширина" кода
От: Константин Л.  
Дата: 28.04.08 15:46
Оценка: 1 (1) +5
Здравствуйте, licedey, Вы писали:

[]

L>Это дело привычки. Сам стараюсь писать код так, чтобы не приходилось пользоваться горизонтальным скрол баром.

L>Хотя с другой стороны, сейчас работаю над проектом, в котором используется MSHTML. Так приходится себя заставлять
L>писать вложенные if'ы, до 20 штук доходит. А все потому, что при получении интерфейса на любой элемент, нужно вызывать Release после использования. Напрягает жутко. Иногда просто забиваю на все релизы, отчего memory leaks бывают до 1GB при определенных условиях . Вот она цена привычки. Странно, что клиент закрывает на это глаза.

странно, что ты закрываешь на это глаза

открой для себя мир smart pointers (hint: ATL::CComPtr, _com_ptr_t, boost::intrusive_ptr)

[]
Re: Проверка условий и "ширина" кода
От: licedey  
Дата: 28.04.08 15:20
Оценка: :))) :)))
Здравствуйте, AlexKr, Вы писали:

AK>Добрый день.


AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.


Это дело привычки. Сам стараюсь писать код так, чтобы не приходилось пользоваться горизонтальным скрол баром.
Хотя с другой стороны, сейчас работаю над проектом, в котором используется MSHTML. Так приходится себя заставлять
писать вложенные if'ы, до 20 штук доходит. А все потому, что при получении интерфейса на любой элемент, нужно вызывать Release после использования. Напрягает жутко. Иногда просто забиваю на все релизы, отчего memory leaks бывают до 1GB при определенных условиях . Вот она цена привычки. Странно, что клиент закрывает на это глаза.

Правильно так:
if( SUCCEEDED( ob1->QueryInterface( &i1 ) ) )
{
  if( SUCCEEDED( i1->QueryInterface( &i2 ) ) )
  {
    // далее порядка еще 10 подобных вызовов
    ...
    i2->Release();
  }
  i1->Release();
}


По привычке часто пишу так:
if( FAILED( ob1->QueryInterface( &i1 ) ) )
  return;
if( FAILED( i1->QueryInterface( &i2 ) ) )
  return;
Проверка условий и "ширина" кода
От: AlexKr  
Дата: 28.04.08 07:38
Оценка: +4
Добрый день.

Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.

bool func1()
{
    if( condition1 )
    {
        do1();

        if( condition2 )
        {
            do2();

            if( condition3 )
            {
                do3();

                if( condition4 )
                {
                    do4();

                    return true;
                }
            }
        }
    }

    return false;
}


Конечно, он читаемый, но, почему бы не писать так:

bool func1()
{
    if( !condition1 )
        return false;

    do1();

    if( !condition2 )
        return false;

    do2();

    if( !condition3 )
        return false;

    do3();

    if( !condition4 )
        return false;

    do4();

    return true;
}
Re: Проверка условий и "ширина" кода
От: _Jane_ Украина  
Дата: 05.06.08 08:44
Оценка: 2 (1) +2
Здравствуйте, AlexKr, Вы писали:

У нас принято не более 4х уровней вложенности.
Как правило, такой код не однообразен и может быть разделён на несколько функций.
Либо второй вариант, но скорее с флагами, т.к. у функции с несколькими точками выхода есть свои недостатки.

AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.


AK>
AK>bool func1()
AK>{
AK>    if( condition1 )
AK>    {
AK>        do1();

AK>        if( condition2 )
AK>        {
AK>            do2();

AK>            if( condition3 )
AK>            {
AK>                do3();

AK>                if( condition4 )
AK>                {
AK>                    do4();

AK>                    return true;
AK>                }
AK>            }
AK>        }
AK>    }

AK>    return false;
AK>}
AK>


AK>Конечно, он читаемый, но, почему бы не писать так:


AK>
AK>bool func1()
AK>{
AK>    if( !condition1 )
AK>        return false;

AK>    do1();

AK>    if( !condition2 )
AK>        return false;

AK>    do2();

AK>    if( !condition3 )
AK>        return false;

AK>    do3();

AK>    if( !condition4 )
AK>        return false;

AK>    do4();

AK>    return true;
AK>}
AK>
Jane
Re[2]: Проверка условий и "ширина" кода
От: Кодт Россия  
Дата: 28.04.08 15:05
Оценка: +2
Здравствуйте, andrey.desman, Вы писали:

AD>
AD>bool func1
AD>{
AD>    return condition1 && (do1(), true) &&
AD>           condition2 && (do2(), true) && 
AD>           condition3 && (do3(), true) &&
AD>           condition4 && (do4(), true);
AD>}
AD>

А теперь попробуйте в отладчике, по шагам...
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[3]: Проверка условий и "ширина" кода
От: licedey  
Дата: 30.04.08 12:53
Оценка: :))
Здравствуйте, Константин Л., Вы писали:

КЛ>Здравствуйте, licedey, Вы писали:


КЛ>[]


L>>Это дело привычки. Сам стараюсь писать код так, чтобы не приходилось пользоваться горизонтальным скрол баром.

L>>Хотя с другой стороны, сейчас работаю над проектом, в котором используется MSHTML. Так приходится себя заставлять
L>>писать вложенные if'ы, до 20 штук доходит. А все потому, что при получении интерфейса на любой элемент, нужно вызывать Release после использования. Напрягает жутко. Иногда просто забиваю на все релизы, отчего memory leaks бывают до 1GB при определенных условиях . Вот она цена привычки. Странно, что клиент закрывает на это глаза.

КЛ> странно, что ты закрываешь на это глаза


КЛ>открой для себя мир smart pointers (hint: ATL::CComPtr, _com_ptr_t, boost::intrusive_ptr)


КЛ>[]


Когда проект только начинался, я за основу взял исходники где не используются смарты.
Я в таком же стиле стал писать, но не курсе был что нужно release вызывать. Догнал только
когда обнаружил что память безвозвратно теряется . Тогда стал лепить CComPtr в старый код,
отчего тот стал падать. Думаю теперь через макросы решить проблему...
Типа:
#define R3(a,b,c) (a->Release(),b->Release(),c->Release())
Re[5]: Проверка условий и "ширина" кода
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.04.08 19:19
Оценка: +2
Здравствуйте, Кодт, Вы писали:

К>Проблемы в том, что в С/С++ с давних (наверное, с фортрановских) времён принято точки расставлять по строкам.


Еще надо добавить "Майкрософтом".

Почему-то для С++ многое довольно не удобно. Но это ведь не значит, что сам подход плох?

Лично мне проще читать код более компактный. Ну, зачем мне искать логику по странице если ее можно собрать водном месте?

Почему-то те кто программируют на императивных языках (особенно на С-подобных) частенько плюют на понятность кода в угоду, скажем, отладке (или еще чему-то). Но ведь более понятный и краткий код сам по себе снижает необходимость в отладке.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Проверка условий и "ширина" кода
От: Константин Л.  
Дата: 28.04.08 08:37
Оценка: +1
Здравствуйте, AlexKr, Вы писали:

AK>Добрый день.


AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.


не только тебе. предпочитаю 2-ой вариант

[]
Re: Проверка условий и "ширина" кода
От: C0s Россия  
Дата: 28.04.08 08:52
Оценка: +1
Здравствуйте, AlexKr, Вы писали:

AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"?


конечно, многое зависит от правил оформления кода в конкретной команде, помноженных на консервативность программистов команды.
но в целом, ты прав, что за читабельность надо бороться.
лично я считаю, что надо делать как можно "уже"

AK>Я постоянно встречаю такой код


могу только посочувствовать
Re: Проверка условий и "ширина" кода
От: Roman Odaisky Украина  
Дата: 28.04.08 09:42
Оценка: +1
Здравствуйте, AlexKr, Вы писали:

AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"?


Flat is better than nested.

http://www.python.org/dev/peps/pep-0020/

Однако «широкий» вариант имеет то преимущество, что там можно аккуратнее управлять видимостью и временем жизни переменных:
if(X x = getX())
{
    do1();
    if(Y y = getY())
    {
        do2();
    }
    // здесь y.~Y()
    do3();
}
До последнего не верил в пирамиду Лебедева.
Re[2]: Проверка условий и "ширина" кода
От: AlexKr  
Дата: 28.04.08 09:59
Оценка: +1
Да, пару раз спорил, помню такой аргумент. Но мой вывод, что такой код в 95% случаев пишется без аргумента, просто так.
Re[6]: Проверка условий и "ширина" кода
От: Кодт Россия  
Дата: 03.05.08 23:13
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>Почему-то для С++ многое довольно не удобно. Но это ведь не значит, что сам подход плох?


— Понимаешь, сынок, есть такое слово "Родина"

VD>Лично мне проще читать код более компактный. Ну, зачем мне искать логику по странице если ее можно собрать водном месте?


VD>Почему-то те кто программируют на императивных языках (особенно на С-подобных) частенько плюют на понятность кода в угоду, скажем, отладке (или еще чему-то). Но ведь более понятный и краткий код сам по себе снижает необходимость в отладке.


Чисто для флейма могу предположить, что мега-конъюнкция или мега-дизъюнкция не повышает читаемость.
Потому что в ней одновременно закодированы две вещи
— булево выражение (в том числе, обладает коммутативностью)
— последовательность выражений (некоммутативность)
И с разбегу сказать, важна ли здесь последовательность (обеспечивающая предусловие, или хотя бы оптимизирующая вычисление сложных выражений — когда менее вероятные предикаты ставятся в начале) — это вопрос.
Перекуём баги на фичи!
Re: Проверка условий и "ширина" кода
От: andrey.desman  
Дата: 28.04.08 08:14
Оценка:
Здравствуйте, AlexKr, Вы писали:



bool func1
{
    return condition1 && (do1(), true) &&
           condition2 && (do2(), true) && 
           condition3 && (do3(), true) &&
           condition4 && (do4(), true);
}
Re[2]: Проверка условий и "ширина" кода
От: AlexKr  
Дата: 28.04.08 09:55
Оценка:
...Вместо do() может быть несколько строк кода.
Re[2]: Проверка условий и "ширина" кода
От: jazzer Россия Skype: enerjazzer
Дата: 28.04.08 12:11
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Однако «широкий» вариант имеет то преимущество, что там можно аккуратнее управлять видимостью и временем жизни переменных:

RO>
RO>if(X x = getX())
RO>{
RO>    do1();
RO>    if(Y y = getY())
RO>    {
RO>        do2();
RO>    }
RO>    // здесь y.~Y()
RO>    do3();
RO>}
RO>


твой код не эквивалентен обсуждаемому
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Проверка условий и "ширина" кода
От: Miroff Россия  
Дата: 29.04.08 08:25
Оценка:
Здравствуйте, AlexKr, Вы писали:

AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.


У меня такой код часто получается в результате автоматической генерации из таблицы решений. Заниматься ручной оптимизацией, конечно, можно, но влом.
Re[2]: Проверка условий и "ширина" кода
От: Erop Россия  
Дата: 29.04.08 09:59
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Однако «широкий» вариант имеет то преимущество, что там можно аккуратнее управлять видимостью и временем жизни переменных:

А в "узком" не судьба, что ли do7 в отдельный блоок затолкать, если оно надо?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Проверка условий и "ширина" кода
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.04.08 17:55
Оценка:
Здравствуйте, Кодт, Вы писали:

AD>>
AD>>bool func1
AD>>{
AD>>    return condition1 && (do1(), true) &&
AD>>           condition2 && (do2(), true) && 
AD>>           condition3 && (do3(), true) &&
AD>>           condition4 && (do4(), true);
AD>>}
AD>>

К>А теперь попробуйте в отладчике, по шагам...

Это проблемы компилятора/отладчика. В том же Немерле мы по такому коду "ходим" на раз. Спасибо IT!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Проверка условий и "ширина" кода
От: Left2 Украина  
Дата: 30.04.08 18:57
Оценка:
L>Думаю теперь через макросы решить проблему...
L>Типа:
L>#define R3(a,b,c) (a->Release(),b->Release(),c->Release())
сдаётся мне что за такое решение коллеги которые будут потом сопровождать твой код оторвут тебе чего-нить.
Так что никаких макросов, юзай правильно смартпоинтеры и ничего падать не будет.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[4]: Проверка условий и "ширина" кода
От: Кодт Россия  
Дата: 30.04.08 19:08
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Это проблемы компилятора/отладчика. В том же Немерле мы по такому коду "ходим" на раз. Спасибо IT!


А в VB это ещё в 6 версии было. (А может, и в 5, не помню).
Проблемы в том, что в С/С++ с давних (наверное, с фортрановских) времён принято точки расставлять по строкам.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[4]: Проверка условий и "ширина" кода
От: Кодт Россия  
Дата: 30.04.08 19:08
Оценка:
Здравствуйте, licedey, Вы писали:

L>Когда проект только начинался, я за основу взял исходники где не используются смарты.

L>Я в таком же стиле стал писать, но не курсе был что нужно release вызывать. Догнал только
L>когда обнаружил что память безвозвратно теряется . Тогда стал лепить CComPtr в старый код,
L>отчего тот стал падать. Думаю теперь через макросы решить проблему...
L>Типа:
L>#define R3(a,b,c) (a->Release(),b->Release(),c->Release())

Думаю, проблему решить надо через кровавый рефакторинг.
(Кровавым он называется потому, что при этой методике компилятор будет валить в тебя еррорами, пока всё не переделаешь по-человечески).
Зато потом вздохнёшь свободно.

Лепить желательно не CComPtr, потому что у него есть неявное приведение к голому указателю. Будет мало крови при компиляции.

Находишь все QueryInterface, Release и переделываешь тип найденных рядом переменных на умные указатели. И убираешь Release.
Переделываешь сигнатуры функций (кроме интерфейсных, увы), чтоб они принимали только умные указатели.
Переделываешь все структуры и классы, чтоб их члены были умными.

Можно пойти таким путём: искать все вхождения Iblablabla* и заменять на intrusive_ptr<Iblablabla>.
А там, где голые указатели почему-то нужны — там, увы, восстанавливаешь.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[7]: Проверка условий и "ширина" кода
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.05.08 08:51
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Чисто для флейма могу предположить, что мега-конъюнкция или мега-дизъюнкция не повышает читаемость.

К>Потому что в ней одновременно закодированы две вещи
К>- булево выражение (в том числе, обладает коммутативностью)
К>- последовательность выражений (некоммутативность)
К>И с разбегу сказать, важна ли здесь последовательность (обеспечивающая предусловие, или хотя бы оптимизирующая вычисление сложных выражений — когда менее вероятные предикаты ставятся в начале) — это вопрос.

Странная логика. А последовательность ифов (гора, точнее сказать) лучше передает суть?

Тут скорее в другую сторону надо посмотреть. Ведь все эти проверки чего-то означают. Не так ли?
А раз так, то логично было бы разнести их на отдельные функции с разумными именами. Тогда код бы стал понятнее, и что самое забавное, еще короче!
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Проверка условий и "ширина" кода
От: Tesh США  
Дата: 11.06.08 20:09
Оценка:
Здравствуйте, AlexKr, Вы писали:

AK>Добрый день.


AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.


[Skipped]

вместо
    if ( condition1 )
        return false;

предпочитаю писать
    if ( condition1 )
    {
        return false;
    }


т.к. второй вариант позволяет избежать возможной ошибки, когда другой девелопер решит исправить этот код, добавив например do(); таким образом:
    if ( condition1 )
        do();
        return false;

а так получится со вторым вариантом
    if ( condition1 )
    {
        do();
        return false;
    }

да и смотрится лучше, другое дело что вложенностей таких какие описаны у вас — не бывает
+есть такое понятие как корпоративный стандарт оформления кода
... << RSDN@Home 1.2.0 alpha 4 rev. 1090>>
Re[2]: Проверка условий и "ширина" кода
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.06.08 06:35
Оценка:
Здравствуйте, licedey, Вы писали:

L>Это дело привычки. Сам стараюсь писать код так, чтобы не приходилось пользоваться горизонтальным скрол баром.

L>Хотя с другой стороны, сейчас работаю над проектом, в котором используется MSHTML. Так приходится себя заставлять
L>писать вложенные if'ы, до 20 штук доходит. А все потому, что при получении интерфейса на любой элемент, нужно вызывать Release после использования. Напрягает жутко. Иногда просто забиваю на все релизы, отчего memory leaks бывают до 1GB при определенных условиях :). Вот она цена привычки. Странно, что клиент закрывает на это глаза.

Если тебе недоступны ни smart pointers, ни другой аналогичный подход — тогда вспомни про goto:

  Object *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL; // и так далее
  int rc = 0;
  //...
  if (FAILED(action1)) { rc = ERROR_BUKA; goto Cleanup; }
  // ...
  if (FAILED(action2)) { rc = ERROR_ZUKA; goto Cleanup; }
  // ура! получилось!
  rc = SUCCESS;
Cleanup:
  if (p1) Object_delete(p1);
  if (p2) Object_delete(p2);
  if (p3) Object_delete(p3);
  if (p4) Object_delete(p4);
  return rc;
}


Были у меня разработки, где можно было писать только так... никакого C++ и прочих "высоких" средств не допускалось. Но проблем это не составляло — после того, как метод построения кода специфицирован вплоть до имени метки, объяснён и понят, споров вокруг идеологии и реализации уже не было.

L>По привычке часто пишу так:

L>
L>if( FAILED( ob1->QueryInterface( &i1 ) ) )
L>  return;
L>if( FAILED( i1->QueryInterface( &i2 ) ) )
L>  return;
L>


Ну вот и перепиши на любой доступный, но не оставляющий ликов, вариант :)
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.