Здравствуйте, Erop, Вы писали:
E>... так что я думаю, дело в том, что стандартный assert убог, а остальные не стандартизованы. E>Если, когда, в STL добавят нормальный assert его станут использовать и в библиотеках
ИМХО, конечно, это не вопрос стандартности, но культуры программирования, тестирования и сопровождения. Точнее её отсутствия. С другой стороны, сама она не возникнет, культуру надо прививать. Делать же это обычно никому не хочется. То что ассёрты как приём программирования являются причиной спров о нужности, просто показатель.
Здравствуйте, Alexey Chen, Вы писали:
AC>ИМХО, конечно, это не вопрос стандартности, но культуры программирования, тестирования и сопровождения. Точнее её отсутствия. С другой стороны, сама она не возникнет, культуру надо прививать. Делать же это обычно никому не хочется. То что ассёрты как приём программирования являются причиной спров о нужности, просто показатель.
Да нет, вроде как про пользу assert'ов особо-то никто тут не спорил
Не нравилось поведение стандартного assert'а
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, MaximE, Вы писали:
ME>Чтобы ассерты имели хоть какой-то смысл необходим полный code coverage при тестировании со всеми возможными входными данными, т.е. чтобы при тестировании отработали все ветки кода на реальных данных. Часто это обеспечить очень сложно
Можешь привести пример, когда полный code coverage действительно очень сложен?
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, MaximE, Вы писали:
ME>>Чтобы ассерты имели хоть какой-то смысл необходим полный code coverage при тестировании со всеми возможными входными данными, т.е. чтобы при тестировании отработали все ветки кода на реальных данных. Часто это обеспечить очень сложно
A>Можешь привести пример, когда полный code coverage действительно очень сложен?
Здравствуйте, MaximE, Вы писали:
ME>>>Чтобы ассерты имели хоть какой-то смысл необходим полный code coverage при тестировании со всеми возможными входными данными, т.е. чтобы при тестировании отработали все ветки кода на реальных данных. Часто это обеспечить очень сложно
A>>Можешь привести пример, когда полный code coverage действительно очень сложен?
ME>Не могу ни вспомнить, ни придумать
Еще вопрос: если мы имеем полный code coverage — нафига нам вообще нужны assert'ы?
Здравствуйте, Аноним, Вы писали:
А>Почему в большинстве библиотек которые я видел очень редко используются assert'ы? А>Типа "настоящие" программисты ошибок не совершают...
CPPUNIT_ASSERT чем плох?
Конечно, я слышал кучу мнений по поводу юнит-тестирования, но большинство из них сводилось к "некогда мне тут фигней заниматься"
ME>Чтобы ассерты имели хоть какой-то смысл необходим полный code coverage при тестировании со всеми возможными входными данными, т.е. чтобы при тестировании отработали все ветки кода на реальных данных.
Кхм... То есть, если ассерты помогут выловить не все ошибки, а только 90% — то это совершенно бесполезная фича...
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, MaximE, Вы писали:
ME>>>>Чтобы ассерты имели хоть какой-то смысл необходим полный code coverage при тестировании со всеми возможными входными данными, т.е. чтобы при тестировании отработали все ветки кода на реальных данных. Часто это обеспечить очень сложно
A>>>Можешь привести пример, когда полный code coverage действительно очень сложен?
ME>>Не могу ни вспомнить, ни придумать
A>Еще вопрос: если мы имеем полный code coverage — нафига нам вообще нужны assert'ы?
Здравствуйте, MaximE, Вы писали:
A>>Еще вопрос: если мы имеем полный code coverage — нафига нам вообще нужны assert'ы?
ME>Мне они не нужны, я их не использую )
Alxndr wrote:
> Здравствуйте, MaximE, Вы писали: > > A>>Еще вопрос: если мы имеем полный code coverage — нафига нам вообще > нужны assert'ы? > > ME>Мне они не нужны, я их не использую ) > > Ну, вопрос был "вообще", теоретический. > > А что используешь? Сразу abort()?
Если после ошибки есть возможность восстановиться, то throw, если нет, то abort().
-- Maxim Yegorushkin
No Microsoft product was used in any way to write or send this text.
If you use a Microsoft product to read it, you're doing so at your own risk
Alxndr wrote: > A>>Можешь привести пример, когда полный code coverage действительно > очень сложен? > ME>Не могу ни вспомнить, ни придумать > Еще вопрос: если мы имеем полный code coverage — нафига нам вообще нужны > assert'ы?
Для проверки что код не только покрыт, но еще и работает.
Здравствуйте, MaximE, Вы писали:
>> Если после ошибки есть возможность восстановиться, то throw, если нет, то abort().
Так если выше не перехватывать исключение, то обработка его по-умолчанию приведет к abort.
На счет применения assert на этапе кодирования:
1) можно применять assert, чтобы не замарачиваться изобретением способа себя подстраховать в процессее отладки, а заниматься чисто кодированием, тогда — сам написал — сам отгребай свои assert'ы.
2) если я беру чужой недописаный код, где есть куча assert, код надо доделать...а если он не рабочий — поди выясни нормально причину ошибки — только факт известен.
На счет применения assert при сдаче в release — считаю, что всегда нужно корректно завершать работу приложения, а abort — он и в Африке аборт — приложение "уйдет по-английски".
Здравствуйте, omka, Вы писали:
O>Здравствуйте, MaximE, Вы писали:
>>> Если после ошибки есть возможность восстановиться, то throw, если нет, то abort().
O>Так если выше не перехватывать исключение, то обработка его по-умолчанию приведет к abort.
Верно.
Есть ситуации, когда известно, что это критический функционал, если он не работает, только abort() имеет смысл. Если бросать в этом случае исключение, читающий код может подумать, что можно восстановаться, поймав исключение, т.е. кинув исключение в таком случае я не точно передаю смысл моих намерений.
[]
O>На счет применения assert при сдаче в release — считаю, что всегда нужно корректно завершать работу приложения, а abort — он и в Африке аборт — приложение "уйдет по-английски".
Это может быть верно для гуи приложение. Для серверов мне ближе такой подход:
Rule of Repair: Repair what you can — but when you must fail, fail noisily and as soon as possible.
Software should be transparent in the way that it fails, as well as in normal operation. It's best when software can cope with unexpected conditions by adapting to them, but the worst kinds of bugs are those in which the repair doesn't succeed and the problem quietly causes corruption that doesn't show up until much later.
Therefore, write your software to cope with incorrect inputs and its own execution errors as gracefully as possible. But when it cannot, make it fail in a way that makes diagnosis of the problem as easy as possible.
Consider also Postel's Prescription:[10] “Be liberal in what you accept, and conservative in what you send”. Postel was speaking of network service programs, but the underlying idea is more general. Well-designed programs cooperate with other programs by making as much sense as they can from ill-formed inputs; they either fail noisily or pass strictly clean and correct data to the next program in the chain.
However, heed also this warning:
The original HTML documents recommended “be generous in what you accept”, and it has bedeviled us ever since because each browser accepts a different superset of the specifications. It is the specifications that should be generous, not their interpretation.
-- Doug McIlroy
McIlroy adjures us to design for generosity rather than compensating for inadequate standards with permissive implementations. Otherwise, as he rightly points out, it's all too easy to end up in tag soup.
Здравствуйте, MaximE, Вы писали:
ME>Верно.
ME>Есть ситуации, когда известно, что это критический функционал, если он не работает, только abort() имеет смысл. Если бросать в этом случае исключение, читающий код может подумать, что можно восстановаться, поймав исключение, т.е. кинув исключение в таком случае я не точно передаю смысл моих намерений.
Так надо кинуть исключение, которое точно бы передало смысл намерений.
И потом — обработка исключений полностью лежит на том, кто использует Ваш класс.
Можно в документации указать какая причина вызывает это исключение в коде, и рекомендации по его обработке, или вопрос в том, чтобы по-меньше положить работы на плечи пользователей класса?
omka wrote: > Так надо кинуть исключение, которое точно бы передало смысл намерений.
Вот мы обнаружили повреждение строки (например, str[str.size()]!=0). Что
делать?
Имеем поврежденный блок памяти, обнаружить повреждение обычно нельзя.
Исключение тоже кинуть нельзя — стэк может быть разрушен.
Поэтому лучше всего в такой ситуации записать core dump и не делать вид,
что ничего не случилось.
Здравствуйте, Cyberax, Вы писали:
C>Вот мы обнаружили повреждение строки (например, str[str.size()]!=0). Что C>делать?
C>Имеем поврежденный блок памяти, обнаружить повреждение обычно нельзя. C>Исключение тоже кинуть нельзя — стэк может быть разрушен.
C>Поэтому лучше всего в такой ситуации записать core dump и не делать вид, C>что ничего не случилось.
Ну, механизм исключений делался не для того, чтобы делать вид, что ничего не случилось — а локализовать место возникновения ошибки для принятия решения о дальнейшей ходе работы.
В подобном случае именно в точке возникновения ошибки видно, что дальнейшая работа приложения недопустима — не зачем генерировать исключение — это верно.
"Кинуть исключение, которое точно бы передало смысл намерени" — я имел ввиду не на постой кидать исключения, а там, где это нужно.
"На счет применения assert при сдаче в release — считаю, что всегда нужно корректно завершать работу приложения" — может core dump это как раз и есть корректное завершение работы — для системы и самого приложения завершение приложения — самый безопасный выход.
omka wrote: > C>Поэтому лучше всего в такой ситуации записать core dump и не делать вид, > C>что ничего не случилось. > Ну, механизм исключений делался не для того, чтобы делать вид, что > ничего не случилось — а локализовать место возникновения ошибки для > принятия решения о дальнейшей ходе работы.
Вот тебе пример:
void aVeryBadFunction()
{
char arr[10];
for(int f=0;f<20;++f)
arr[10-f-1]=f;
}
void goodFunction()
{
std::string aString;
aString="adfjnaksd";
aVeryBadFunction();
//Приплыли. Такой вот код может дать AE:for(size_t f=0;f<aString.size();++f)
aString[f]=toupper(aString[f]);
}
Все. Стэк разрушен, программа работать будет в зависимости от фазы Луны.
При попытке кинуть исключение мы только все ухудшим.
Называется это "нарушение инвариантов".
> В подобном случае именно в точке возникновения ошибки видно, что > дальнейшая работа приложения недопустима — не зачем генерировать > исключение — это верно.
Точка возникновения ошибки и точка срабатывания assert'а — это обычно
совершенно разные вещи.
> "На счет применения assert при сдаче в release — считаю, что всегда > нужно корректно завершать работу приложения" — может core dump это как > раз и есть корректное завершение работы — для системы и самого > приложения завершение приложения — самый безопасный выход.
code dump — это в любом случае аварийное завершение. "assert" в релизах
как раз противопоказан — так как часто в разы уменьшает быстродействие.
Здравствуйте, omka, Вы писали:
O>Ну, механизм исключений делался не для того, чтобы делать вид, что ничего не случилось — а локализовать место возникновения ошибки для принятия решения о дальнейшей ходе работы.
Не согласен. Предназначен он для простой передачи ошибки от уровня, где ошибка произошла, уровню, который готов эту ошибку обработать. Который о коде, кинувшем исключение, по хорошему вообще не знает.