Сча ! Не могу терпеть , расскажу историю которая со мной реально приключилась.
Код который находится в разработке (много чужого не до конца понятного) все в жутком овральном режиме с требованиями чтобы только заработало , плюс жесткие требования к коду , ни одного лишнего движения которое бы моголо облегчить программирование , не чистка , не рефакторинг , вообще ничего.
В этих условиях я ставлю асерты чере каждые пару строк , хотя бы для того чтобы разобраться в работе алгоритмов.
Заказчику отдается промежуточный код и он с ним что то делает (видимо тестирует).
И ВОТ: От заказчика приходит требование "убрать все асерты и асертоподобные макросы из кода" , аргументируется это примерно так
"Как я могу быть уверен что код работет , если он может выдавать асерты ??? "
Я неделю после этого ходил согнутый , но ничего пришлось вычистить все асерты , и главное код "конечно заработал без багов".
Вот такой вот глубокий маразм встречается на белом свете.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[5]: Почему редко используются assert'ы?
От:
Аноним
Дата:
09.10.05 06:30
Оценка:
Здравствуйте, sch, Вы писали:
sch>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, Cyberax, Вы писали: C>>>Кстати, у ассертов под MSVC есть еще одно интересное применение: C>>>
C>>>То есть assert'ы не просто удаляются из кода, а превращаются в хинты C>>>компилятору.
А>>А можно про это поподробнее, почему это лучше чем ((void)0) в релизе вместо ассерта?
sch>http://msdn.microsoft.com/library/en-us/vccelng/htm/msmod_36.asp:
sch>The __assume keyword passes a hint to the optimizer. The optimizer assumes that the condition represented by expression is true at the point where the keyword appears and remains true until expression is altered (for example, by assignment to a variable). Selective use of hints passed to the optimizer by __assume can improve optimization.
MSDN я читал, но все равно не понял чем лучше ((void)0), поэтому и спрашиваю.
Здравствуйте, minorlogic, Вы писали:
M>Здравствуйте, <Аноним>, Вы писали:
А>>Почему в большинстве библиотек которые я видел очень редко используются assert'ы? А>>Типа "настоящие" программисты ошибок не совершают...
M>Да нет , асерты используются на полную при разработке и отладке , а уже из отлаженных кусков кода обычно удалаяютяс.
asserts удаляются автоматически компилятором и препроцессором во время построения release версии.
Здравствуйте, Аноним, Вы писали:
А>Почему в большинстве библиотек которые я видел очень редко используются assert'ы? А>Типа "настоящие" программисты ошибок не совершают...
очень часто используют. Посмотрите Windows checked билды, там assert-ы на каждом вызове.
Не имеет большого смысла assert-ить свой код, типа
Здравствуйте, pavel_turbin, Вы писали:
_>очень часто используют. Посмотрите Windows checked билды, там assert-ы на каждом вызове. _>Не имеет большого смысла assert-ить свой код, типа
_>
_>имеет смысл assert-ить меж-модульные вызовы и вызовы к операционной системе, пример
_>
_>my_assert( CloseHandle(hFile) ); // обрашение к OS
_>export my_error myfuncchar *a) // вызывается из вне
_>{
_> my_assert(a);
_> if( 0 == a )
_> return invalid_parameter;
_> return ok;
_>}
_>
_>я написал "my_assert", чтобы в debug build он раскрылся в обычный assert, а в relase dump ошибки в лог, если он поддержан.
Это почему еще не имеет смысла ассертить свой код?
Думаю Вам следует прочитать серию статей Александреску про assert'ы и enforcement'ы в C/C++ Users Journal.
Philosophers say that reality defies imagination by being more complex than what our mind can concoct. This is certainly true in the case of software development. There are tons of stories about assertions that were just "impossible to fire," but they actually fired. Time and again, it goes the same way. "This value is certainly positive! That pointer is obviously not null! The array? It's undoubtedly sorted; I'd bet money on that! Why recheck tautologies?" If you're a beginner, you feel like you are wasting your time when you write some assert, but much more often than you initially thought, it's going to fire to save your life. It's all because software development is complex, and anything could happen in a program that is changing. Assertions verify that what you believe is "obviously true" actually stays true.
There is an effective litmus test to differentiate the cases in which you need to use assert and when you need to use genuine error checking: you use error checking for things that could happen, even very improbably. You use assert only for things that you truly believe cannot possibly happen under any circumstances. An assertion that fails always signals a design or a programmer error — not a user error.
On the other hand, you do not want to use assertions to validate return values of functions that might fail. You don't use assert to make sure that malloc worked, that a window creation succeeded, or that a thread was started. You can, use, however, assert to make sure that APIs work as documented. For example, if some API function is documented to always return a positive value, but somehow you suspect it might have a bug, you might want to plant an assert.
Нельзя путать обработку ошибок с отловом багов в коде. Это две большие разницы!
Я присоединяюсь к вопросу. В моем архиве чужих исходников, я не нашел ни одного проекта (библиотеки), где бы последовательно использовались ассерты. Большей частью урывками, в основном для проверки на равенство нулю указателя или использование assert(0) в default блоках оператора switch.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Аноним, Вы писали:
А>>Почему в большинстве библиотек которые я видел очень редко используются assert'ы? А>>Типа "настоящие" программисты ошибок не совершают...
А>Я например часто использую: А>
А>И везде по ходу определения методов SomeClass вместо непосредственно prop2_ использую вызов get_ptop2(), тем самым гарантирую, что я нигде не налажал и значение prop2_ инициализировано верно.
Вообще этот тот случай, когда лучше использовать исключения. Если рассматривать SomeClass как модель данных, то опытный программист помимо структуры данных включает еще код для constraine, то есть определяет код который следит за правильными корректными состояниями модели данных, в случае если пользователь этой структуры вводит модель данных в неправильное состояние — пользовательский код должен получить ошибку, в обьектноориентированных языках для этих целей принято использовать исключения, и пользовательский код обязан переживать такие ситуации, к примеру код, который визуализирует в ГУИ эту структуру должен знать, что при установке значений поля структуры могут быть исключительные ситуации, и нужно уметь правильно это обработать, проверка целостности структуры должна быть заключена в самой структуре, а не на уровне ГУИ.
Бывает правда другая ситуация, вы используете низлежащую функциональность, low level API, и его поведение не достаточно хорошо изучено, есть некоторые непредсказуемые поведения, нет доверия производителю этой функциональности, вот тут после каждого обращения к этому функционалу следует его проверять ассертами, это помимо исключений, которые по прежнему должны улететь в пользовательский код, с тем что бы попробовать еще раз дать шанс заполнить данные, может глюк нижнего ненадежного слоя и не повторится.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[3]: Почему редко используются assert'ы?
От:
Аноним
Дата:
09.10.05 11:08
Оценка:
Здравствуйте, Batiskaf, Вы писали:
B>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, Аноним, Вы писали:
А>>>Почему в большинстве библиотек которые я видел очень редко используются assert'ы? А>>>Типа "настоящие" программисты ошибок не совершают...
А>>Я например часто использую: А>>
А>>И везде по ходу определения методов SomeClass вместо непосредственно prop2_ использую вызов get_ptop2(), тем самым гарантирую, что я нигде не налажал и значение prop2_ инициализировано верно.
B>Вообще этот тот случай, когда лучше использовать исключения. Если рассматривать SomeClass как модель данных, то опытный программист помимо структуры данных включает еще код для constraine, то есть определяет код который следит за правильными корректными состояниями модели данных, в случае если пользователь этой структуры вводит модель данных в неправильное состояние — пользовательский код должен получить ошибку, в обьектноориентированных языках для этих целей принято использовать исключения, и пользовательский код обязан переживать такие ситуации, к примеру код, который визуализирует в ГУИ эту структуру должен знать, что при установке значений поля структуры могут быть исключительные ситуации, и нужно уметь правильно это обработать, проверка целостности структуры должна быть заключена в самой структуре, а не на уровне ГУИ.
B>Бывает правда другая ситуация, вы используете низлежащую функциональность, low level API, и его поведение не достаточно хорошо изучено, есть некоторые непредсказуемые поведения, нет доверия производителю этой функциональности, вот тут после каждого обращения к этому функционалу следует его проверять ассертами, это помимо исключений, которые по прежнему должны улететь в пользовательский код, с тем что бы попробовать еще раз дать шанс заполнить данные, может глюк нижнего ненадежного слоя и не повторится.
Ниже по ветке я уже говорил, что assert'ы нужны для разработчика кода, не для пользователя exe'шника.
Все данные вводимые пользователем проверяются сразу при их вводе (вот где используютеся код constraine класса SomeClass, напр. is_valid_prop2()), в случае неудачной проверки, выводится сообщение, где предлагается ввести корректные данные, или выбрасывается исключение, зависит от типа приложения. Коду SomeClass неважно где его будут использовать, поэтому он не знает что делать в случае неверного prop2_: исключение, код ошибки, сообщение... Задача разработчика класса SomeClass предоставить набор методов валидации данных; задача разработчика приложения, использующего SomeClass, пропускать все входные данные для SomeClass, вводимые пользователем, через соответствующие функции валидации, и написать код для обработки некорректных входных данных.
Т. о. при таком подходе свойства класса prop2_ и prop1_ не могут быть инициированы неверными значениями.
Здравствуйте, ssi, Вы писали:
ssi>Это почему еще не имеет смысла ассертить свой код? ssi>Думаю Вам следует прочитать серию статей Александреску про assert'ы и enforcement'ы в C/C++ Users Journal.
это все так красиво выглядит теории. На практике, когда необходимо достичь определеного качества кода за заданных промежуток времени, чем-то приходиться пренебрегать. Конечно, если время неограниченно, то очень хорошо "проассертить" весь код, но я думаю, что лучше прогнать ещё пару unit-test или дописать коменты, чем возиться с assert-ом. Так или иначе assert-ы уйдут из releasa сами.
pavel_turbin wrote:
> ssi>Это почему еще не имеет смысла ассертить свой код? > ssi>Думаю Вам следует прочитать серию статей Александреску про > assert'ы и enforcement'ы в C/C++ Users Journal. > это все так красиво выглядит теории. На практике, когда необходимо > достичь определеного качества кода за заданных промежуток времени, > чем-то приходиться пренебрегать.
Неправильная практика. У меня лично ассерты многократно окупаются на
времени отладки. Ну а их расстановка почти ничего не стоит по времени
(пару лишних клавиш нажать во время написания кода).
Здравствуйте, pavel_turbin, Вы писали:
_>это все так красиво выглядит теории. На практике, когда необходимо достичь определеного качества кода за заданных промежуток времени, чем-то приходиться пренебрегать. Конечно, если время неограниченно, то очень хорошо "проассертить" весь код, но я думаю, что лучше прогнать ещё пару unit-test или дописать коменты, чем возиться с assert-ом. Так или иначе assert-ы уйдут из releasa сами.
А что с ними возится, тупо ставишь ассерты на все входные данные хотя бы, уже кучу багов можно отловить. По времени это сопоставимо с написанием коментария. Собственно, ассерты — это коментарий для релиза.
Здравствуйте, Аноним, Вы писали:
А>Ниже по ветке я уже говорил, что assert'ы нужны для разработчика кода, не для пользователя exe'шника.
Да собственно и исключения тоже для программиста. Просто если провести грань между средствами верификации, то исключения я применяю там где нужно оповестить пользовательский код о неправильной операции, а ассерты я применяю на уровне моего системного кода для проверки неотлаженного низлежащего кода.
А>Все данные вводимые пользователем проверяются сразу при их вводе (вот где используютеся код constraine класса SomeClass, напр. is_valid_prop2()), в случае неудачной проверки, выводится сообщение, где предлагается ввести корректные данные, или выбрасывается исключение, зависит от типа приложения. Коду SomeClass неважно где его будут использовать, поэтому он не знает что делать в случае неверного prop2_: исключение, код ошибки, сообщение... Задача разработчика класса SomeClass предоставить набор методов валидации данных; задача разработчика приложения, использующего SomeClass, пропускать все входные данные для SomeClass, вводимые пользователем, через соответствующие функции валидации, и написать код для обработки некорректных входных данных.
да, только сообщениями пользоваться не стоит, SomeClass может использоваться в самых разных средах, с разными типами аллертов. Принимать решение о выбрасывании сообщений должен пользовательский код, если он может показать месаджбокс или распечатать html, или бибикнуть на экране деньгомата в банке, в зависимости от системы.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[5]: Почему редко используются assert'ы?
От:
Аноним
Дата:
09.10.05 13:11
Оценка:
Здравствуйте, Batiskaf, Вы писали:
А>>Все данные вводимые пользователем проверяются сразу при их вводе (вот где используютеся код constraine класса SomeClass, напр. is_valid_prop2()), в случае неудачной проверки, выводится сообщение, где предлагается ввести корректные данные, или выбрасывается исключение, зависит от типа приложения. Коду SomeClass неважно где его будут использовать, поэтому он не знает что делать в случае неверного prop2_: исключение, код ошибки, сообщение... Задача разработчика класса SomeClass предоставить набор методов валидации данных; задача разработчика приложения, использующего SomeClass, пропускать все входные данные для SomeClass, вводимые пользователем, через соответствующие функции валидации, и написать код для обработки некорректных входных данных.
B>да, только сообщениями пользоваться не стоит, SomeClass может использоваться в самых разных средах, с разными типами аллертов. Принимать решение о выбрасывании сообщений должен пользовательский код, если он может показать месаджбокс или распечатать html, или бибикнуть на экране деньгомата в банке, в зависимости от системы.
Так вроде и написано
>> Коду SomeClass неважно где его будут использовать, поэтому он не знает что делать в случае неверного prop2_: исключение, код ошибки, сообщение...
Здравствуйте, Аноним, Вы писали:
А>Ниже по ветке я уже говорил, что assert'ы нужны для разработчика кода, не для пользователя exe'шника.
вот и нет. Посмотрите на Windows XP Checked build. Он полон assert-ов. Их цель выловить ошибки в вызовах и использования API. Вместо того, чтобы вернуть FALSE, checked build генерирюет assert, который ловится отладчиком. Я всегда перед релизом прогоняю тесты покрайней мере один раз на checked. Периодически нахожу что-нибудь.
_>это все так красиво выглядит теории. На практике, когда необходимо достичь определеного качества кода за заданных промежуток времени, чем-то приходиться пренебрегать. Конечно, если время неограниченно, то очень хорошо "проассертить" весь код, но я думаю, что лучше прогнать ещё пару unit-test или дописать коменты, чем возиться с assert-ом. Так или иначе assert-ы уйдут из releasa сами.
IMHO, ставить или не ставить ассерты — дело привычки, кто-то ставит много, кто-то мало или вообще не ставит. Но они очень полезны при отладке проекта, и особенно полезны, когда проект достаточно большой, и изменение одного из модулей потенциально может затронуть другие части. Поэтому я всегда ставлю досаточно много ассертов на логику, чтобы хоть какое предупреждение получить в ситуации, когда отлаженный модуль перестал корректно работать из-за изменений в других частях проекта. В общем, это не панацея, но помощь в отладке есть.
имеет если кодом вызываешь не только ты
потому что с каким параметром будет вызвана функция вообще никто не знает
_>имеет смысл assert-ить меж-модульные вызовы и вызовы к операционной системе, пример
_>
_>my_assert( CloseHandle(hFile) ); // обрашение к OS
_>export my_error myfuncchar *a) // вызывается из вне
_>{
_> my_assert(a);
_> if( 0 == a )
_> return invalid_parameter;
_> return ok;
_>}
_>
_>я написал "my_assert", чтобы в debug build он раскрылся в обычный assert, а в relase dump ошибки в лог, если он поддержан.
а вот это вообще перл
my_assert( CloseHandle(hFile) ); // обрашение к OS
C>То есть assert'ы не просто удаляются из кода, а превращаются в хинты C>компилятору.
Спасибо, узнал про наличие такого ключевого слова
Но в реальном проекте я бы побоялся ипользовать его везде где я использую ASSERT — хотя бы потому что бывают такие куски кода
if (param == NULL)
{
ATLASSERT(param && "Invalid parameter, but error is not critical");
return E_FAIL;
}
Боюсь, что в случае __assume вместо ASSERT оптимизатор этот кусок вообще выкинет.
I>my_assert( CloseHandle(hFile) ); // обрашение к OS
I>
Кстати, из-за высокой вероятности спутать ASSERT и VERIFY мы у себя в проекте вообще отказались от использования VERIFY — если надо сделать ASSERT на возвращаемое значение — пиши
Здравствуйте, Аноним, Вы писали:
А>Почему в большинстве библиотек которые я видел очень редко используются assert'ы? А>Типа "настоящие" программисты ошибок не совершают...
Потому что assert — это самое убогое средство отладки, какое можно придумать.
В дебаг-версии он выводит assertion failed и убивает задачу по abort. В релиз-версии не вычисляет аргумент (повод для ошибок, когда важная функциональность случайно внесена внутрь assert-выражения).