Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.
Здравствуйте, AlexKr, Вы писали:
AK>Добрый день.
AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.
Это — давнее суеверие, что в функции должно быть только одно место для выхода (single return).
Оно частично имеет смысл для С (освобождение ресурсов перед выходом), но для С++, очевидно, оно абсурдно, потому что исключение может вылететь практически из любой строчки.
Здравствуйте, AlexKr, Вы писали:
AK>Добрый день.
AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.
Здравствуйте, AlexKr, Вы писали:
AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"?
конечно, многое зависит от правил оформления кода в конкретной команде, помноженных на консервативность программистов команды.
но в целом, ты прав, что за читабельность надо бороться.
лично я считаю, что надо делать как можно "уже"
AK>Я постоянно встречаю такой код
Здравствуйте, 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>
Здравствуйте, 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();
}
[]
L>Это дело привычки. Сам стараюсь писать код так, чтобы не приходилось пользоваться горизонтальным скрол баром. L>Хотя с другой стороны, сейчас работаю над проектом, в котором используется MSHTML. Так приходится себя заставлять L>писать вложенные if'ы, до 20 штук доходит. А все потому, что при получении интерфейса на любой элемент, нужно вызывать Release после использования. Напрягает жутко. Иногда просто забиваю на все релизы, отчего memory leaks бывают до 1GB при определенных условиях . Вот она цена привычки. Странно, что клиент закрывает на это глаза.
странно, что ты закрываешь на это глаза
открой для себя мир smart pointers (hint: ATL::CComPtr, _com_ptr_t, boost::intrusive_ptr)
Здравствуйте, AlexKr, Вы писали:
AK>Только мне не нравится этот код или это тайный заговор — делать код "шире"? Я постоянно встречаю такой код. Пишут так и новички и люди, чей стаж больше моего. Причем уровень вложенности часто доходит до 6-8. Здесь не обсуждается вариант с else.
У меня такой код часто получается в результате автоматической генерации из таблицы решений. Заниматься ручной оптимизацией, конечно, можно, но влом.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Однако «широкий» вариант имеет то преимущество, что там можно аккуратнее управлять видимостью и временем жизни переменных:
А в "узком" не судьба, что ли do7 в отдельный блоок затолкать, если оно надо?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, 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())
L>Думаю теперь через макросы решить проблему... L>Типа: L>#define R3(a,b,c) (a->Release(),b->Release(),c->Release())
сдаётся мне что за такое решение коллеги которые будут потом сопровождать твой код оторвут тебе чего-нить.
Так что никаких макросов, юзай правильно смартпоинтеры и ничего падать не будет.
Здравствуйте, VladD2, Вы писали:
VD>Это проблемы компилятора/отладчика. В том же Немерле мы по такому коду "ходим" на раз. Спасибо IT!
А в VB это ещё в 6 версии было. (А может, и в 5, не помню).
Проблемы в том, что в С/С++ с давних (наверное, с фортрановских) времён принято точки расставлять по строкам.
Здравствуйте, 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>.
А там, где голые указатели почему-то нужны — там, увы, восстанавливаешь.