Стоит ли обрабатывать ошибки через assert?

slonishka

преподносят много сюрпризов начинается еще на слове assert.

Serab

а шо не так с этим словом?

slonishka

матерное оно

slonishka

хотя при чем тут сюрпризы?

Serab

не, ну давай уже прямо: не надо им пользоваться, оно не из libc, или еще чего. Правда не понимаю :grin:

slonishka

а, ну вот то, что оно матерное - это для тебя сюрприз! :DDD

Serab

:lol: кто ищет, тот найдет.

slonishka

ну я пижжу на него, потому что это как-то не по-человечески -
вот просто брать и ёбаться он рантайм кондишен.
но я не знаток, может оно там уже обернуто в каком-нибудь libc или еще где.
типа только при сборке в дебаааге. я сборщикам тоже не доверяю.
ты только не подумай, что я параноик.

Serab

ты только не подумай, что я параноик.
в наше время никому нельзя верить :grin:
Не, ну как, он же не "просто падает". В дебаге вызывает брейкпоинт, в релизе — летит эксепшен и юзеру достается "интернал еггог". Хз, все равно лучше: получаешь бэктрэйс от более логичного места.
А придумывать нормальные описания к ошибкам типа "бля, откуда тут нулевой указатель" как-то ломает.
Вообще assert как раз для параноиков, если не доверяешь тому, кто вызвал внутреннюю функцию — напиши assert. Некоторые пишут даже assert( this != 0 ) :ooo:

slonishka

в релизе — летит эксепшен и юзеру достается "интернал еггог"
а в C как?

slonishka

Вообще assert как раз для параноиков
да, и что значит КАК РАЗ?

Serab

а в C как?
А в C — longjump, вестимо.

Serab

да, и что значит КАК РАЗ?
как раз — значит, что твоя ненависть к assert'у не должна прибалять аргументов в пользу того мнения, что ты параноик.

vall

руки оторвать, по самую жопу

Serab

ололо, ну если не уметь пользоваться, то конечно.
Что плохого в том, что вместо чистого падения еще можно будет сообщить хотя бы примерно, что вообщше произошло?
Успешно используем longjump, обернутый в собственный класс в проекте, который должен работать и компилироваться более чем девятью тысячами компиляторов. Некоторые даже слова namespace не знают :grin:, не говоря уже о нормальной реализации исключений (да, C++)
Так что руки отрывать будешь в другом месте.

vall

для этого есть готовые решения, breakpad например

Serab

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

Serab

Breakpad provides client libraries for each of its target platforms. Currently, these exist for Windows on x86 and Mac OS X on both x86 and PowerPC. A Linux implementation has been written and is currently under review.
этого мало, очень мало.

slonishka

Что плохого в том, что вместо чистого падения еще можно будет сообщить хотя бы примерно, что вообщше произошло?
то, что какой-нибудь еблан обязательно сунет в assert какую-
нибудь фигню, по поводу которой вовсе не нужно падать.
или обратно: если ты по поводу предиката какого-то сраного падать
собрался, то how dare you утверждать, "что вообще произошло"?
любая программа может обеспечить надежность своих данных (там где надо) умнее,
чем "ой, 32768 == 32768, причудливо как-то, наверное память сгорела (или гамма-излучение
ебну-ка я корку, а разработчик пусть в ней нихуя не поймет - вот будет ржака!"

Serab

любая программа может обеспечить надежность своих данных (там где надо) умнее,
чем "ой, 32768 == 32768, причудливо как-то, наверное память сгорела (или гамма-излучение
ебну-ка я корку, а разработчик пусть в ней нихуя не поймет - вот будет ржака!"
альтернатива-то какая, можешь объяснить? Писать без ошибок? Ну так тогда и assert'ы можно нормальные писать.
Все-таки программы отлаживают перед тем, как выпускать и кроме корки разработчик получает еще нормальную интсрукцию по вопроизведению от тестера.

vall

не не, эти ассерты-багоны нужны в первую очередь чтоб другой пейсатель сразу понял что это он пидарас и не так зовёт этот кода кусок.

Serab

то, что какой-нибудь еблан обязательно сунет в assert какую-
нибудь фигню, по поводу которой вовсе не нужно падать.
можешь привести пример?
Вот, пускай в функцию типа strlen передали нулевой указатель. Что будешь делать?

slonishka

return EINVAL;

vall

return EINVAL;
FAIL

Serab

Ух ты. А тот программер, который не догадался проверить, что передает в функцию нулевой указатель, по-твоему догадается проверить, что эта функция вернула? А потом ты увидишь тот же coredump из-за порчи памяти (потому что этот прогер, получивший EINVAL воспримет его как нормальное значение но уже без всяких шансов отследить настоящую ошибку. ПОБЕДА.
Я понял твою позицию. Надо писать без ошибок, поэтому assert не нужен.
Повторю аналогию из соседнего треда: «надо писать без ошибок, поэтому отладчики не нужны».

slonishka

там много фейла. какую конкретно генеральную идею тебе пояснить?

vall

возвращаемые ошибки какбы обычно отрицательные
и неявная обработка нулевых указателей это уродство по определению.

slonishka

А тот программер, который не догадался проверить, что передает в функцию нулевой указатель, по-твоему догадается проверить, что эта функция вернула?
догадается по определению. пользуешься интерфейсом - пользуйся интерфейсом, а не продуктом собственной фантазии.
я имею в виду не strlen, а int fucked_up_strlen(char *, size_t * видимо. это не так уж важно.
Повторю аналогию из соседнего треда: «надо писать без ошибок, поэтому отладчики не нужны».
отладчики иногда полезны, чтобы понять, почему этот лозунг - тупая формулировка правильной концепции.

Serab

какая неявная? не падение программы?

slonishka

не, ну лично я конкретно strlen так делать бы не стал.
я вообще strlen не использую.
но на каком-то уровне уже можно начинать проверять.
главное договориться, где мы все проверили и начинается гамма-излучение.
вот и все.
про ошибки опечатка.

Serab

Договориться-то можно, но люди делают ошибки. От этого не уйдешь. Можно себя обманывать и теоретизировать дальше, а можно писать безопасный код, который помогает обнаруживать ошибки, а не пытается их маскировать.

vall

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

vall

ну да, если уж делать такую хуету то использовать ssize_t =)

Serab

А почему работа какой-нибудь библиотеки должна падать клиентскую программу? Уж лучше пусть сообщит «бага, обратитесь в службу поддержки».
Да, если сегфолт, то тоже поймут, что бага, но так хотя бы можно продолжить работу на других данных.

slonishka

т.е. у меня проблема номер 42 вынесена из кода
в сторону проектирования о самфин.
просто в промышленности все одинаковое.
и есть много вещей, по поводу которых определяем единственный SPoT.

slonishka

безопасный код НЕ ПАДАЕТ в strlen(0).
тестирование не заметит этой ошибки тупого разработчика.
я гарантирую это.

Serab

Да, assert тоже не приводит к падению, лол.

agaaaa

Скажу своё слово в поддержку .
Ассерты надо писать в случае если ты предполагаешь ошибку в собственном коде.
Для внешнего интерфейса предназначены коды возврата и механизм исключений.

Serab

А segfault? Вон, его предлагает «возвращать».
А ты сказал очевидную вещь. Почему она в поддержку , я не понял :grin:
Вот я про то и говорю, что если ты пишешь assert, то у тебя есть шанс отловить его и сообщить наружу (исключением или кодом возврата) типа «мы тут сплоховали, обратитесь в поддержку». А если не проверять, то будет segfault, ура.

slonishka

Программа должна гарантированно падать как можно раньше.
ага. на самом деле, я думаю, лучше ответит на твои вопросы,
потому что я привык работать с более-менее хорошим кодом.
я все свои проекты и проекты на работе (in general) помню.

vall

ты не поверишь, segfault можно обработать
и я не предлагаю его возвращать.

agaaaa

М.... а в C fail assert'а разве не крешит программу сразу?
segfault - это и есть исключение.

Serab

Ок, т.е. по-твоему, это правильный подход?

Serab

М.... а в C fail assert'а разве не крешит программу сразу?
assert assert'у рознь. Я же говорю, у нас в одном специфическом проекте assert'ы реализованы через longjump.

vall

случаев где код действительно может пиздануться неизвестно как и это можно разумно обоработать настолько мало что да

slonishka

Я же говорю, у нас в одном специфическом проекте assert'ы реализованы через longjump.
не, для этого изобретения необходим отдельный тред!
но я не хочу на longjump ругаться, ну его нахуй.
назовите это pidorassert, чтобы отразить нежность явления.

slonishka

хотя нежность, конечно, особая.. ;)

Werdna

любая программа может обеспечить надежность своих данных (там где надо) умнее,
чем "ой, 32768 == 32768, причудливо как-то, наверное память сгорела (или гамма-излучение
ебну-ка я корку, а разработчик пусть в ней нихуя не поймет - вот будет ржака!"
Да, это пиздец.
Не буду говорить кто мне как-то сказал, на вопрос "и что теперь с этим ассертом делать?" — ну типа gdb есть.
Бля, пиздец пидерастия эти асерты.

Serab

на вопрос "и что теперь с этим ассертом делать?" — ну типа gdb есть.
блять, педерастия — это AV не там, где ошибка, а попозже. А assert сам сообщает, в какой строчке он произошел.
Я же говорю, психологические травмы детства беспокоят. Запомнил «ассерт», а надо было запомнить имя, фамилию и адрес чувака, который проектировал вашу систему и разрешил такие ассерты, которые только gdb отыскиваются. Ну либо того прогера, которому не разрешали так сделать, а он сделал.

Serab

    а в C как?
А в C — longjump, вестимо.
Ок, перечитал тут немного.
По поводу C отвечу так: не знаю, не прогал на нем ничего серьезного. Но вопрос открыт.
Дальше все про C++.
Про longjump заикнулся по следующей причине: в одном проекте (портирование C++-кода) столкнулись (не я, более опытные предшественники) с тем, что исключениями пользоваться нельзя, а убирать ассерты было сцыкотно (просто уже выработат вэй поэтому решили сделать longjump в начало выполнения соответствующей подсистемы. В итоге пользователю сообщалось что-то типа «internal error бла-бла». Все сделано аккуратно и никаких побочных эффектов и мемори ликов не происходит.
В C++ я привык к нормальным assert'ам-исключениям, вписывающимся в общую иерархию исключений. Т.е. его можно ловить и не ловить в разных местах. Никто не отменял правило «ловить только то, что знаешь как обработать» и прочие методики работы с исключениями (см. как минимум все книги Саттера, еще его блог). Таким образом assert следует ловить только в крайних местах: на стыке с клиентским кодом (в функциях, вызываемых извне т.е. где уже просто нельзя пускать его дальше.
Дальше. Assert — не для взаимодействия с пользователем и его появление — по определению ошибка программы. Ну это даже написал :grin:, думаю тут никаких вопросов.
Assert'ы не выключаются в Release версиях. Есть отдельная версия assert'а, которая выключается в release-версиях. Используется редко и только в местах, где профайлером доказано повышение эффективности.
Что тут-то не так?
Еще раз перечитайте, возможно вы все это время думали, что я за стандартный assert, прерывающий все моментально (травмы детства).

Dasar

Еще раз перечитайте, возможно вы все это время думали, что я за стандартный assert, прерывающий все моментально (травмы детства).
стоило все-таки использовать стандартные термины, а не придумывать свои.
1. вы используете систему исключений засунутую в assert.
2. под С через longjmp вы сделали свой механизм исключений, чтобы поддержать п.1
вот так и нужно было писать, а то assert-ы - assert-ы
на лицо, нарушение интерфейса, т.к. интерфейс assert-а подразумевает останов программы, а у тебя assert кидает исключение.
как минимум об этом стоило сразу и говорить.

Katya19

А могут ли господа — противники использования ассертов (и особенно сторонники возврата EINVAL) — рассказать нам, пишут ли они промышленный код, и если да — то для каких продуктов (хотя бы примерно, можно без громких названий). Мне с трудом верится, что человек, который профессионально занимается программированием, может говорить такие нелепости.

erotic

преподносят много сюрпризов начинается еще на слове assert
Вот ты до сих пор озабоченный =)
Обсуждали же уже - ассертят то, что стопудово должно выполняться, а если не выполняется, то это полный пиздец (типа ты прибавил к двум два, получил три, и дальше твоей программе бессмысленно работать).
В релиз ассерты не кладутся, чтобы, во-первых, не донимать релиз лишними проверками, а во-вторых, не ронять программу, если при тестировании в дебаге что-то проглядели.
Вопросы?
P.S. Весь срач тут не читал, отвечаю конкретно тебе.

Serab

В релиз ассерты не кладутся, чтобы, во-первых, не донимать релиз лишними проверками, а во-вторых, не ронять программу, если при тестировании в дебаге что-то проглядели.
Вопросы?
а вот с этим и я не согласен, в релиз тоже надо бы их покласть, иначе как-то совсем голимо (я выше писал)

Serab

стоило все-таки использовать стандартные термины, а не придумывать свои.
Ну вот в этом месте я исходил из следующего. Все-таки в словаре на слово «assert» не будет ничего указано про «моментальное падение».
Еще: встречался с разными реализациями этого механизма, поэтому не подозревал, что тут все так травмированы тем ужасным assert'ом.

evolet

это все разные механизмы, почему-то названные одинаково
типа, когда не знаешь, как назвать функцию, называй ProcessData

Serab

это все разные механизмы, почему-то названные одинаково
Это разные реализации одного и того же действия (ну посмотри уже перевод слова assert, а?). Так что названы они именно так правомерно.

evolet

я посмотрел перевод, не бэ!)
(поясню на всякий случай, есть некоторые традиции в использовании слов, терминология, и имхо assert - это уже такой термин, а для терминов нет особого смысла смотреть перевод в словаре)
и какое действие?
и все-таки: вот есть действие - "обработать данные", у него бывает огромное кол-во "разных реализаций" ну и че? Формально все верно. но смысла оперировать таким понятием нет, ибо слишком общё (как и перевод слова assert).

Serab

и какое действие?
Проверить, что договоренности в силе, сложные инварианты алгоритмов. Вообще проверить, что алгоритм верно выполняется. А что после этого делать — это уже не оговаривается.
и все-таки: вот есть действие - "обработать данные", у него бывает огромное кол-во "разных реализаций" ну и че? Формально все верно. но смысла оперировать таким понятием нет, ибо слишком общо (как и перевод слова assert).
абсурд, вот именно, assert — конкретная вещь, а не «что-то общее».

erotic

а вот с этим и я не согласен, в релиз тоже надо бы их покласть, иначе как-то совсем голимо (я выше писал)
Не читал. Для проверок в релизе использую что угодно, только не assert. А после Бачановской паники и assert'ы перестал использовать.

Serab

что угодно, только не assert.
я весь тред пытаюсь добиться ответа на вопрос: «какая альтернатива?» и что-то все молчат, как партизаны.
А после Бачановской паники и assert'ы перестал использовать.
нервная система не выдерживает? :)

erotic

Альтернатива у каждого своя, мб?
Для обычных ошибок исключения обычно - типа, передали в функцию нулевой указатель, нет файла, нет доступа к файлу, невозможно забиндить сокет, хреновый конфиг передали и прочая лабуда. В вот если есть какие-то инварианты в классе, которые должны всегда соблюдаться, то для них можно ассерты замутить. Потому что если они не соблюлись - это ошибка программиста.

margadon

я вот бачана с пианистом слушал, но тоже не смог понять чем по факту ассерты так страшны :) разве что при автоматическом бездумном использовании - как, в сущности, и любой другой инструмент...
к сожалению, не каждая функция на неверных данных соображает, что ей скормили что-то "не то", некоторые функции продолжают делать вид, что они не при делах и маскируют начало ошибки. Кажется разумным в процессе получения внешних данных (например, в самом начале функции) сразу проверять все критичные данные на вшивость и если что - вываливаться/писать в лог/звенеть в колокольчик - но НЕ МОЛЧАТЬ. Особенно это касается больших проектов, где ты никогда не предугадаешь, кто в следующий момент захочет воспользоваться твоей либой и что у него с рассудком.
Если, конечно, проект целиком в голове, то вероятно это всё жутчайший оверкилл, но тогда и многие конструкции С++ излишни, например ключевое слово private :)

Serab

как, в сущности, и любой другой инструмент...
именно.
маскируют начало ошибки
именно.
Полностью согласен :grin:

erotic

я вот бачана с пианистом слушал, но тоже не смог понять чем по факту ассерты так страшны
Однажды пришел Левис и сказал ассерты не использовать ;)

margadon

аа) вопрос снят
стилистическое единство бывает важнее внедрения полезных фич

slonishka

P.S. Весь срач тут не читал, отвечаю конкретно тебе.
вопросов нет, самолет в воздухе ты не соберешь и котов не выпасешь. =)
тут был не срач, зря не читал.

erotic

вопросов нет, самолет в воздухе ты не соберешь и котов не выпасешь. =)
тут был не срач, зря не читал.
Я тебе поверил и почитал. Зря. Интересные мысли, конечно, есть, но ничего нового для себя пока не вынес, и в итоге вряд ли вынесу, так что по прежнему считаю тред срачем. Ну т.е. каждый все равно останется при своем мнении.
Тебе ведь не докажешь, что в релиз ассерты не компилятся и ничего не упадет.
А про то, что ты не используешь strlen, загоняться не стоит.

Ivan8209

> А в C — longjump, вестимо.

ASSERT(3) NetBSD Library Functions Manual ASSERT(3)

NAME
assert -- expression verification macro

SYNOPSIS
#include <assert.h>

assert(expression);

DESCRIPTION
The assert macro tests the given expression and if it is false, the
calling process is terminated. A diagnostic message, consisting of the
text of the expression, the name of the source file, the line number and
the enclosing function, is written to stderr and the abort(3) function is
called, effectively terminating the program.

If expression is true, the assert macro does nothing.

The assert macro may be removed at compile time with the cc(1) option
-DNDEBUG.

DIAGNOSTICS
The following diagnostic message is written to stderr if expression is
false:

"assertion \"%s\" failed: file \"%s\", line %d, function \"%s\"\n", \
"expression", __FILE__, __LINE__, __func__);

SEE ALSO
cc(1 _DIAGASSERT(3 abort(3)

STANDARDS
The assert macro conforms to ISO/IEC 9899:1999 (``ISO C99'').

HISTORY
A assert macro appeared in Version 6 AT&T UNIX.

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

Ivan8209

> Еще раз перечитайте, возможно вы все это время думали,
> что я за стандартный assert, прерывающий все моментально
> (травмы детства).
Я пропустил, а в чём, собственно, проблема с тем самым assert,
который даёт abort?
---
...Я работаю антинаучным аферистом...

Serab

Да это все ясно, меня тут подвело, что у нас этот механизм реализован вручную.
И про longjump я тоже подробно объяснил, мог бы увидеть.

Ivan8209

Я, например, не очень понимаю, зачем создавать исключение, если
программа уже вероятно разрушена и её надо перезапускать.
Собственно, мы так и делаем, у нас проще, быстрее и надёжнее
перезапустить, чем разбирать, что же, собственно, произошло,
дожидаясь аппаратного перезапуска.
---
"Quae medicamenta non sanat, ferrum sanat,
quae ferrum non sanat, ignis sanat."

Serab

Я, например, не очень понимаю, зачем создавать исключение, если
программа уже вероятно разрушена и её надо перезапускать.
у нас специфика такая, продаем SDK, пускай клиент сам решает. Тем более, что assert не всегда означает порчу памяти. В подавляющем большинстве случаев это обычная ошибка и переинициализация/запуск на других входных данных не страдает от наведенных ошибок.
Есть и продукты-приложения (с богатым GUI ну там, пожалуй, тот же аргумент уместен. Да и хотелось бы сохранить файлы, с которыми работал пользователь (может быть в другое место или для возможности восстановления при последующем запуске :confused:). Точно не знаю, сам не видел ассертов из выпущенного продукта, его разработкой не я занимаюсь.

Ivan8209

Понятно. Ты совсем про другой ассерт.
---
...Я работаю...
Оставить комментарий
Имя или ник:
Комментарий: