Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.147.49.182] |
|
Страницы: (37) « Первая ... 24 25 [26] 27 28 ... 36 37 ( Перейти к последнему сообщению ) |
Сообщ.
#376
,
|
|
|
Цитата D_KEY @ Ну вот Линус, к примеру, не выберет. Он прекрасно обходится структурами и функциями, принимающими их по указателю первым параметром, кодами возврата и макросами. И счастлив при этом. Потому что такой кодестайл, потому, что это для него оправдано его причинами.Если ты пишешь на Си и везде на костылях делаешь ООП, исключения и шаблоны, то не стоило ли выбрать C++? Цитата D_KEY @ Можно думать, аналогичных кодестайлов у Плюсников не бывает. У которых тоже есть свои причины на это.Если ты, наоборот, взял плюсы, но решил ничего из этого не использовать, то стоит задуматься над тем, а не дал ли бы тебе Си какие-то преимущества(скажем, комьюнити)? Но опять же, не в этом вопрос. Ты снова поменял местами причину и следствие. Я выберу подходящий инструмент, когда пойму, что мне нужно будет создать. А не наоборот, выбрав инструмент, начну проектировать с учётом этого. (Утрирую, конечно, мои решения могут быть мне навязаны, и почему бы опять не кодестайлом. Но мы ведь не об этой ситуации, верно?) С этой точки зрения я не буду втюхивать в C-программу код возврата ERR_USERBREAK, которому предстоит пройти по всему стеку вложенных вызовов. ...Что-что? А... порты поосвобождать и документы позакрывать по дороге... мда, это проблема. Ну так разве это не вопрос архитектуры, который я продумаю заранее, или я ни разу не архитектор, а какой-нибудь иммутабельный функционер? |
Сообщ.
#377
,
|
|
|
Цитата D_KEY @ Обычно подобный пример рассматривают в литературе и статьях по common lisp с его conditions и restarts Охотно верю, что исключения и коды возврата не единственный способ решения этой задачи. Вообще, спасибо, если не забуду - гляну. |
Сообщ.
#378
,
|
|
|
Цитата D_KEY @ Возможно. Но никому не нравится результат. С исключениями сложнее, а exception safety вряд ли вообще можно проанализировать полноценно. Добавлено Цитата OpenGL @ А вот это никак не парсится. Я недавно приводил пример двух функций - как статический анализатор поймёт, где код возврата, который надо проверить, а где обычный параметр? |
Сообщ.
#379
,
|
|
|
При том, что у тебя внутри вызываемой функци может возникать исключение, которое ты не ждешь. Цитата OpenGL @ Ну давай рассуждать ровно в рамках этого же сценария, но в плюсах, т.е. выделение памяти через new. Ты хочешь сказать, что от него ты bad_alloc не ожидаешь? Не всегда. Иногда я могу ожидать nullptr. Я тебе уже выше об этом писал и D_KEY выше об этом написал. К слову, вот еще один сценарий, когда ты будешь течь, со своими исключениями: void f() { int* p = new int(7); g(); // may throw delete p; // okay if no exception } // memory leak if g() throws Именно вот про такие сценарии, я тебе и говорю. Да ты где то выше это исключение может быть и обработаешь, но ресурса у тебя уже нет. Ты можешь начать аппелировать к RAII, но извини - это из серии как надо делать. В язык это не вшито, никто не будет за тебя контролировать твои утечки. Ловить выше - вот это объяснение? Так ты можешь тем самым контекст какой нибудь попортить, данные не сохранить, потерять ресурс, поиметь утечку и т.д. Вариантов куча. Внутри - это где? Я бы не был столь уверен. Но речь идет совершенно не об этом. Цитата OpenGL @ Давай уж и idris или malbolge приплети, чего уж мелочиться-то. Тут C vs С++ тема, если ты не заметил. Я их приплел как некие альтернативы С++, которые выставляют свою безопасную систему типов и исключений. Не более. А что это? Блин, ты все new оборачиваешь в try/catch ? Так все делают? Я не знаю на счет тебя, но я уверен что так делают не все. Я тебе соответственно и задаю вопрос - что делать, если во время выделения ресурса, тебя выкинет нехрен из функции? Даже если ты не забудешь обрабатывать исключения от этой функции. Я не забываю проверять коды возврата, а ты не забываешь обрабатывать исключения. Но вон bad_alloc ты выхватишь 100%, потому что ты выше написал, что не будешь оборачивать функцию с помощью try/catch(...), а будешь обрабатывать только те исключения, которые она явно кидает. Соответственно ты улетишь в какой нибудь catch снаружи, и поимеешь утечку в том месте, где ты не поймал это исключение. Цитата OpenGL @ Ну ты же с чего-то предполагаешь в си, что код возврата, который возвращаешь ты, обрабатывается наверху? Эээ нет, не нужно подменять понятия, мы работаем в текущей функции, вот мы про нее речь и ведем. Я тоже не могу знать что выше кто то обрабатывает код возврата, да мне на это и плевать по факту. Я работаю в контексте текущей функции, получаю невалдиный ресурс, если могу - выясняю в чем причина, пишу в лог, возвращаю какой нибудь Null, вместо ресурса, подразумевая что выше проверят. Но мне абсолютно фиолетово что там будет выше, на данном этапе я все дела в контексте этой функции выполнил. А вот ты, с исключениями, надеешься на слой выше, потому что по другому у тебя не получится. Ну почему нет никакой информации, у тебя есть описание поведения этой функции. А вот об ошибках, которые она может генерировать, у тебя может и не быть полной картины. Цитата OpenGL @ И это говорит человек, в сценарии которого программист не забывает проверять malloc и при этом забывает, что new кидает bad_alloc Ты не читатель? Я нигде не писал что ты забудешь словить bad_alloc от явного вызова new, вот найди - где я такое писал? Зачем же ты придумываешь тогда? Я тебе писал, что ты можешь выхватить bad_alloc, сам того не зная. Например внутри этой функции CreateOrLoadSomeResource, внутри, в ее реализации, понимаешь? Не снаружи, гдеты ее вызываешь, а в ней самой, гдето там внутри, может происходить выделение памяти, через оператор new, и внутри этой функции какой нибудь горе программист забыл проверить исключение bad_alloc, и оно полетело уже выше, за пределы тела этой функции, прямо к тебе в руки. Но ты не ожидаешь от нее bad_alloc, потому что Цитата OpenGL @ Аааа, так ты всегда без багов пишешь Ну так бы сразу и сказал. Снимаю шляпу и завидую Ээээ. О чем ты? Как это следует из процитированного? Я в упор не понимаю. Когда ты на Си пишешь, у тебя все функции гарантированно не кидают программные исключения, хоть с багами, хоть без багов пиши. В Си, к твоему сведению нет исключений. Если ты не знал. Цитата OpenGL @ Какое ещё нафиг "кикие именно исключения" в контексте сферическовакуумной функции? Не, тебя тоже ну нафиг. Напишешь что-то, на что ответов не было - отвечу, иначе игнор. Так в этом и вся фишка, что ты понятия не имеешь какие эта функция кидает исключения. Соответственно ты не можешь гарантировать что ты все исключения от этой функции обрабатываешь. |
Сообщ.
#380
,
|
|
|
Цитата Wound @ Не знаю, как OpenGL, я не поимею, и при этом мне фиолетово на исключения. Любые и везде. Достичь того же на кодах возврата сложнее, и постоянно есть где ошибаться. Но вон bad_alloc ты выхватишь 100%, потому что ты выше написал, что не будешь оборачивать функцию с помощью try/catch(...), а будешь обрабатывать только те исключения, которые она явно кидает. Соответственно ты улетишь в какой нибудь catch снаружи, и поимеешь утечку в том месте, где ты не поймал это исключение. |
Сообщ.
#381
,
|
|
|
Цитата OpenGL @ Я недавно приводил пример двух функций - как статический анализатор поймёт, где код возврата, который надо проверить, а где обычный параметр? Ну обычно код возврата возвращается как раз. Или хотя бы возвращается признак ошибки. Тогда проверка очень простая. Но даже в твомэем кейсе, если не ошибаюсь, coverity вроде могла понять, что ты создал переменную, передал ее в функцию, в которой ей могли присвоить значение, но ты дальше ничего с ней не делаешь. Обычно коды являются int'ами или enum'ами, так что тут тоже несложно проверить. На код ревью так же легче заметить пропуск проверки кодов, чем проблемы с exception safety. Но вообще я за исключения Добавлено Цитата Qraizer @ Цитата D_KEY @ Возможно. Но никому не нравится результат.С исключениями сложнее, а exception safety вряд ли вообще можно проанализировать полноценно. Слушай, а не подскажешь инструменты? |
Сообщ.
#382
,
|
|
|
Цитата Wound @ Есть. Описаны в Стандарте языка в разделе, описывающим Стандартную библиотеку. В Си, к твоему сведению нет исключений. Если ты не знал. Добавлено Цитата D_KEY @ Я не интересовался. Но представляю, как это можно сделать. Теоретически, любой статический анализатор можно этому научить. В конце концов, Borland C++ 4.xx умел диагностировать неожидаемые исключения при компиляции, так что задача отследить вызовы nothrow() функций и считать их т.о. безопасными, чтобы проанализировать контекст любой функции на предмет изменений в нелокальном контексте только такими функциями и всегда безотказными конструкциями языка, хоть и трудоёмко, но технически несложно. Слушай, а не подскажешь инструменты? |
Сообщ.
#383
,
|
|
|
Цитата Qraizer @ Есть. Описаны в Стандарте языка в разделе, описывающим Стандартную библиотеку. В новом стандарте? Я лично не слышал про программные исключения в сях. И не помню что бы там были try/catch. Про новый стандарт Сей не в курсе, может там и появилось что-то. |
Сообщ.
#384
,
|
|
|
Цитата Qraizer @ Не знаю, как OpenGL, я не поимею, и при этом мне фиолетово на исключения. Любые и везде. Достичь того же на кодах возврата сложнее, и постоянно есть где ошибаться. А у тебя не было случаев, когда сторонняя функция обещала не кидать исключений ни при каких обстоятельствах, ты хотел на этой базе построить уже свои гарантии, а потом оказывалось, что реальность другая? |
Сообщ.
#385
,
|
|
|
Цитата Wound @ Ты можешь начать аппелировать к RAII, но извини - это из серии как надо делать. В язык это не вшито, никто не будет за тебя контролировать твои утечки. Не говори ерунды. У нас на работе даже вчерашние студенты спустя пару месяцев начинают понимать, что такое RAII и более-менее вменяемо его юзать. Никаких ручных new/delete, mutex.lock()/mutex.unlock(), и буфер в памяти выделяют через std::vector. А всего-то надо для этого им показать, что деструктор вызывается всегда и автоматически - тогда люди тупо сами начинают активно использовать эту его особенность. Цитата Wound @ Ловить выше - вот это объяснение? И "ловить выше", и ответ на твой вопрос "зачем" - у всего было развёрнутое объяснение. Цитата Wound @ Внутри - это где? В исходниках винды. Цитата Wound @ А что это? Ты у меня спрашиваешь? Разумеется, тебе виднее, что написал ты, я же могу сказать только, что это совершенно точно не ответ на вопрос, который я задавал Цитата Wound @ Я тоже не могу знать что выше кто то обрабатывает код возврата, да мне на это и плевать по факту. БИНГО. Я тоже не могу знать всей картины, и просто предполагаю, что его там обработают. Не обработали - не мои проблемы. Всё то же самое, только автоматически. Цитата Wound @ Я бы не был столь уверен. Но речь идет совершенно не об этом. С чего бы не об этом, если я неоднократно указывал именно на это - что исключения (+ RAII, естетсвенно) позволяют писать более предсказуемые прораммы? Озвучь что ли тогда, о чём ты. Цитата Wound @ Не снаружи, гдеты ее вызываешь, а в ней самой, гдето там внутри, может происходить выделение памяти, через оператор new, и внутри этой функции какой нибудь горе программист забыл проверить исключение bad_alloc, и оно полетело уже выше, за пределы тела этой функции, прямо к тебе в руки. Я понял, что ты про это, но ты так и не ответил на вопрос, почему у тебя программист-автор этой функции при её реализации забыл сделать проверку того, кинет ли bad_alloc исключение, но при этом не забыл проверить malloc, а без ответа на него твоя эта фраза лишена смысла. Или предполагается, что он у тебя тоже забыть может? Тогда, очевидно, в твоём сценарии последствия будут хуже. |
Сообщ.
#386
,
|
|
|
Цитата Wound @ К слову, вот еще один сценарий, когда ты будешь течь, со своими исключениями: А если так: #include <iostream> #include <memory> #include <stdexcept> void g() { throw std::runtime_error(std::string("Bum!")); } void f() { try { std::unique_ptr<int> p(new int(7)); std::cout << *(static_cast<int*>(p.get())) << std::endl; g(); } catch(std::runtime_error &e) { std::cout << e.what() << "\n"; } catch(...) { std::cout << "Случилось страшное!\n"; } } int main() { f(); return 0; } |
Сообщ.
#387
,
|
|
|
Цитата JoeUser @ Цитата Wound @ К слову, вот еще один сценарий, когда ты будешь течь, со своими исключениями: А если так: #include <iostream> #include <memory> #include <stdexcept> void g() { throw std::runtime_error(std::string("Bum!")); } void f() { try { std::unique_ptr<int> p(new int(7)); std::cout << *(static_cast<int*>(p.get())) << std::endl; g(); } catch(std::runtime_error &e) { std::cout << e.what() << "\n"; } catch(...) { std::cout << "Случилось страшное!\n"; } } int main() { f(); return 0; } А так ты тоже потенциально будешь течь в каком нибудь C++14 https://stackoverflow.com/questions/1947255...and-make-unique Добавлено Позже отвечу на длинный пост выше. У меня комп забрали. А с планшета не удобно писать |
Сообщ.
#388
,
|
|
|
Цитата D_KEY @ Нет, но наслышан. Не видел разницы от подобной же ситуации, но с кодами возврата, кроме той, что с кодами такое сплошь и рядом, а с исключениями единичные случаи. Это ли не ответ на вопрос, баг в реализации какой из этих двух парадигм вероятнее просочится в продакшн? А у тебя не было случаев, когда сторонняя функция обещала не кидать исключений ни при каких обстоятельствах, ты хотел на этой базе построить уже свои гарантии, а потом оказывалось, что реальность другая? |
Сообщ.
#389
,
|
|
|
Цитата Wound @ У меня комп забрали Вот это правильно Добавлено Цитата Qraizer @ Нет, но наслышан. Не видел разницы от подобной же ситуации, но с кодами возврата Да я не в плане сравнения с кодами возврата, а в плане твоей уверенности |
Сообщ.
#390
,
|
|
|
Цитата D_KEY @ Вот это правильно Чего это? Добавлено Цитата OpenGL @ Не говори ерунды. У нас на работе даже вчерашние студенты спустя пару месяцев начинают понимать, что такое RAII и более-менее вменяемо его юзать. Никаких ручных new/delete, mutex.lock()/mutex.unlock(), и буфер в памяти выделяют через std::vector. А всего-то надо для этого им показать, что деструктор вызывается всегда и автоматически - тогда люди тупо сами начинают активно использовать эту его особенность. Вся фишка в том, что это не встроенный в синтаксис или язык механизм, это нужно специально писать, делать. Иногда бывает нужно сделать какую нибудь небольшую операцию, у тебя есть какой нибудь HANDLE, и есть функция какая нибудь, да хоть с для работы с тем же ACL, ты выделяешь под нее память с помощью специальной функции, и освобождаешь. Из за такой ерунды никто не будет оборачивать в класс. Допустим я как делал, да очень просто юзал unique_ptr<HANDLE>, и при создании явно указывал deleter, без всяких оберток. Не нужно рассказывать что везде и всюду вы пишете обертки. Я либо не поверю, либо буду думать что у вас там все упоротые. Не бывает так. Потому как довольно часто - это тупо не обоснованно. Цитата OpenGL @ И "ловить выше", и ответ на твой вопрос "зачем" - у всего было развёрнутое объяснение. Ты так и не понял о чем я тебе. Да словишь ты то исключение в функции main, не в этом проблема. Проблема в том, что у тебя испортится контекст выполнения приложения. Т.е. будет утечка ресурса, или еще чего нибудь. Об этом я тебе говорю, а не о том, что поймаешь ты где нибудь это исключение или нет. Цитата OpenGL @ В исходниках винды. То то я как погляжу всякие там kernel32, user32 ит.п. прям пестрят экспортируемыми классами Хотя например какой нибудь OTPLogonProvider действительно реализован через С++ классы. Ядро, на сколько я понимаю на чистом Си там написано, а уже примочки с боку и на шарпах там уже пишут и на плюсах и на чем только не пишут. Цитата OpenGL @ Ты у меня спрашиваешь? Разумеется, тебе виднее, что написал ты, я же могу сказать только, что это совершенно точно не ответ на вопрос, который я задавал Нет, у D_KEY, естественно у тебя. А как по твоему ответ должен выглядеть? Я тебе говорю про то что ты потенциально можешь не знать какие исключения обрабатывать, а ты у меня спрашиваешь почему я коды возврата не забываю проверить, а исключения забываю. Ну блин. В огороде бузина, а в Киеве дядька Цитата OpenGL @ БИНГО. Я тоже не могу знать всей картины, и просто предполагаю, что его там обработают. Не обработали - не мои проблемы. Всё то же самое, только автоматически. Нет, не так. У тебя кидание исключения сродни goto label, с раскруткой стека, т.е. вот в 5 строчке вылетело исключение, значит 6 строчка уже не выполнится. Соответственно если ты на 4 строчке что то делал, и не ожидал что на 5 строчке у тебя произойдет исключение, то то что ты делал похерится, даже если ты не планировал это и все учел, и дело тут не только в bad_alloc, его я приводил исключительно для примера. Это может быть банально забытый обработчик какого то вполне задокументированного исключения. Потому что я не верю что ты на кажду функцию пишешь портянку из catch для оброботки всех исключений, которые может кидать функция. Цитата OpenGL @ С чего бы не об этом, если я неоднократно указывал именно на это - что исключения (+ RAII, естетсвенно) позволяют писать более предсказуемые прораммы? Озвучь что ли тогда, о чём ты. Я вот об этом: Цитата OpenGL @ и помнить о том, что тут может броситься исключение не сложнее, чем помнить о том, что надо код возврата проверить. Я с этим не согласился, и теперь я тебе доказываю почему помнить о том, что тут может броситься исключение сложнее, чем помнить о том, что надо код возврата проверить. Цитата OpenGL @ Я понял, что ты про это, но ты так и не ответил на вопрос, почему у тебя программист-автор этой функции при её реализации забыл сделать проверку того, кинет ли bad_alloc исключение, но при этом не забыл проверить malloc, а без ответа на него твоя эта фраза лишена смысла. Или предполагается, что он у тебя тоже забыть может? Тогда, очевидно, в твоём сценарии последствия будут хуже. Потому что если ты забываешь проверять указатели, то исключения тебе тем более никак не помогут, ты будешь выхватывать ассинхронные исключения, которые тебе придется ловить с помощью __try/__catch/__finally, и твои программные исключения тут совершенно никак не помогут. Соответственно при прочих равных проверку на валидность указателя будешь делать и ты с исключениями и я без исключений. Плюс по сигнатуре функции видно что она возвращает код возврата, который нужно проверить, перед тем как использовать, потому как в С++ обратное чревато проблемами и большими. Просто с кодами возврата проще понять - что функция может возвратить, и что из того, что она возвратила не будет ошибкой. А с исключениями ты вполне можешь даже не подозревать что может кинуть функция. |