Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>>>>>более того — для формально верифицированного кода они не нужны.
EP>>>·>Для формально верифицированного их разве кто-то пишет?
EP>>>Я имею в виду то, что после того как есть результат формальной верификации, можно их выключить и это никак не повлияют на корректность.
EP>·>Если код формально верифицируется, то ассерты не нужны. Вообще. Смысл?
EP>Был код с ассертами -> формально верифицировали его -> выключили ассерты. Это иллюстрация на тему:
Если код формально верифицирован — ассерты можно тупо удалить. Формальная верификация — сильная, но дорогая техника доказательства корректности кода, которая полностью заменяет ЮТ и ассерты.
EP>>>Более того, юнит-тест конкретного компонента может успешно пройти при наличии бага, или например двойного бага — то есть false positive. При этом внутренний assert мог поймать эти баги на этом же прогоне. То есть assert'ы это отличное дополнение unit-тестов.
EP>·>А конкретнее? Если ассерт можешь написать, почему это же нельзя выразить тестом?
EP>Например двойная ошибка в коде. Из-за первой ошибки перешёл в неправильное состояние, из-за второй перешёл из неправильного в состояние подобное правильному. И вроде бы тест случай проверил, но ошибку не выявил.
EP>При этом assert может элементарно проверять состояние между ошибками. А вот соответствующий юнит-тест мог бы быть на порядки менее очевидным, если вообще возможным.
Если ты вдруг полагаешь, что где-то может быть ошибочное состояние (т.е. хочешь написать там ассерт), то
либо воспроизведи это состояние тестом, т.е. ассерт не нужен;
либо почеши голову и убедись, что это состояние невозможно, т.е. ассерт не нужен.
EP>>>То есть ты определись — либо у тебя код оттестирован и defensive programming не нужен, либо не оттестирован и ты тестируешь его на своих пользователях
EP>·>Оттестирован на требуемых спекой сценариях.
EP>У тебя в "cпеке" описаны все сценарии, для всех компонент на всех уровнях?
Зачем на всех уровнях? Ошибка на уровне юнитов будет падать сразу с каким-нибудь bounds checking и видна немедленно и везде. В отличие от ассертов, которые в отключенном состоянии вызовут неопределённое поведение.
А высокоуровневые сценарии должны проходить, да.
EP>>>·>При релизном использовании отключены.
EP>>>Совсем необязательно — я их видел в коммерческом продукте имеющем сотни миллионов установок
EP>·>Гы-гы. Ведь явно не от хорошей жизни, им тупо пришлось использовать ассерты не по назначению.
EP>Без понятия — но проблемы в этом нет. Если нужен over-defenesive, то оставляй assert'ы и в release
Это не имеет смысла, используют инструмент не по назначению. Это уже тогда не ассерты, а обычные проверки.
EP>>>·>Эта ошибка явно прописана в спеке языка
EP>>>Да какая разница — это и есть логическая ошибка в твоём алгоритме.
EP>·>Так она и сломает мой алгоритм, а не совершенно не относящийся к моему алгоритму код.
EP>Программа не выполнила свою задачу, не пришла в обещанный postcondition, не зависимо от того что где поломалось.
Собственно в этом и проблема, что ты говоришь "программа", т.е. весь процесс. Хотя ошибка только в моём алгоритме. Плохо, когда локальная проблема внезапно становится глобальной. Именно за это не любят глобальные переменные, именно поэтому изобрели всякие защищённые режимы и т.п.
EP>>>·>Конечно, корректен, я что ламер некорректный код писать?
EP>>>Тогда тебе и не нужен никакой defensive programming
EP>·>Т.е. предлагаешь какие-то субъективные оценки, гадание на кофейной гуще использовать для принятия решения какие ассерты включать, а какие нет?
EP>Да, субъективные оценки основанные в том числе на объективных данных — тебя что удивляет?
EP>Такие оценки повсеместно используются в софтостроении, и лишь мизерный процент кода формально верифицируется.
EP>Вычисление любого нетривиального свойства кода крупного проекта является алгоритмически неразрешимой задачей 
Т.е. придумали себе сложность и героически её решаем.
EP>·>Так говорю же, использование ассертов не по назначению. Сфейлилось совсем — брось исключение, оно обработается как надо, а если сфейлилось, но не очень опасно, то пожалуйся в лог и продожи работу. Зачем куда-то лететь-то сразу?
EP>Так assert это и есть жёсткий фейл, семантически не менее (а зачастую более) жёсткий чем обычные исключения.
"Опциональный жесткий фейл". Это не звучит для тебя как оксюморон?
EP>·>В общем, подытожу. Ассерты нужны если:
EP>·>1. Плохо дело с юнит-тестами. Ассерт куда угодно воткнуть легко и хоть какой-то эффект есть.
EP>Ассерты полезны и когда плохо и когда хорошо с юнит-тестами. Работают и при юнит и при интеграционных тестах. Позволяют легко выявлять двойные ошибки и подобное. "Втыкаются" элементарно, и сразу по месту. Плюс служат дополнительной документацией (фактически проверяемой)
Вот и воткни ЮТ. Почему обязательно ассерт?
EP>·>2. Плохо дело с логгированием. Нет нормального способа сообщать о каких-то непредвиденных ситуациях.
EP>Это ты не понимаешь семантику assert'а. Assert это очень жёсткий фейл.
Настолько жесткий, что его можно игнорировать в проде. Ха-ха.
EP>·>3. Плохо дело с обработкой ошибок. Проще грохнуть всё приложение, чем кинуть исключение или нормально обработать ошибочную ситуацию.
EP>·>Т.е. получается что ассерт это такой индикатор code smells.
EP>Нет, и тут не верно. Это уже семантически не assert, так как assert опционален.
EP>А то о чём ты говоришь повсеместно используется в C коде, действительно из-за кривой обработки ошибок, и что характерно не опционально.
EP>Assert это не просто "ошибочная ситуация" а-ля неверный пользовательский ввод и т.п., это БАГ в коде.
Который нужно чинить, а не просто игнорировать.