
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.30] |
![]() |
|
Страницы: (37) « Первая ... 28 29 [30] 31 32 ... 36 37 ( Перейти к последнему сообщению ) |
Сообщ.
#436
,
|
|
|
Цитата D_KEY @ Ты не знаком с C++ Core Guidelines? Рекомендую. Про not_null: Declare a pointer that must not be null as not_null Нет, не знаком. Я уже как год пишу на C#. Решил перейти на него. С++ пока забросил. Эта фишка как я понял из 17 стандарта? Добавлено Цитата D_KEY @ Мусорным этот код становится от того, что его приходится писать на каждый вызов. Как я показал выше. И к чему относится картинка с особенной клавиатурой. В случае not_null мне не приходится писать такой код. И никакого мусора нет. Ну так есть тот же механизм с GetLastError . Т.е. тебе не обязательно от каждой функции проверять ошибку она тебе там вернула или еще че то. Ты можешь просто там, где тебе нужно вызвать эту функцию и понять была ли ошибка до этого места или нет. Если нет - значит делай свою следующую операцию, если была - возвращай ошибку, или обрабатывай ее. |
![]() |
|
|
Цитата Wound @ можно так же взять функцию, которая возвращает тебе указатель. Вот как раз это и есть код возврата. Если он нулевой - значит ошибка, если не нулевой, значит все впорядке. Вот не надо так. То есть это нормально, если там действительно не всегда есть значение, то есть nullptr будет не ошибкой, а информацией об отсутствии значения и т.п. Если ошибка, то пусть лучше будет исключение. Тогда опять же можно будет использовать not_null. Мне вот в Kotlin нравится, что для nullable нужно явно ставить у типа ? А по умолчанию оно null быть не может. |
![]() |
Сообщ.
#438
,
|
|
Цитата Wound @ Мог бы просто тогда написать: "Я весь блок Main Оберну в try/catch(...)" и вообще плевать на все эти исключения. ![]() Цитата OpenGL @ Обычно это на самом верху требуется, в int main() каком-нибудь. В остальных случаях catch(...) может быть вставлено временно для отладки, реальной же необходимости в нём я не вижу. Цитата Wound @ Я забыл проверить - значит ты ровно так же забыл обернуть в класс ресурс, и забыл написать обработку исключений. С чего бы? Оборачивается один вид ресурса один раз и потом эта обёртка юзается везде. Обработка исключений аналогично - вставляется только в паре-тройке мест по call stak-у, и всё. Проверка же пишется абсолютно везде. Так что мимо - это не сравнимые вещи. Цитата Wound @ Так перепиши, никаких проблем там возникнуть не может, ты просто перепиши, как считаешь правильным. Зачем? Принесёшь хоть немного нетривиальный пример, тогда и перепишу. Этот же ничем не отличается от твоего первого примера с утечкой, после которого ты и приплёл RAII. Цитата Wound @ С чего вдруг он продолжил работу? Разве что после рестарта, так это уже по сути программа грохнулась, может быть кто то в этот момент другой метод дергал, и там какие важные данные хранились. Потому что я не вижу причин, почему должно быть иначе. ![]() Да нивапрос. Но раз мы не обсуждаем его, то не приплетай аргумент в духе "мы тут не можем бросить исключение потому что что-то испортится", приводя в качестве примера код, где проблема это отсутствие RAII а не исключение. И где тут выдирание из контекста? Речь ровно о том, с чего начался срачик - о том, что легко понять, какие исключения надо обрабатывать тут. Цитата Wound @ приведи мне сигнатуру функции, из которой я пойму какие исключения мне нужно из нее обработать Сигнатуру привести? А чего не имя разрабатываемого модуля, или день рождения жены соседа? Это всё к определению того, какие исключения надо будет обрабатывать, имеет ровно такое же отношение ![]() Ну да, тебе ответили "пусть летит". Привести реальный пример, когда бы оно всё сломало, ты так и не смог. |
Сообщ.
#439
,
|
|
|
Цитата Wound @ Т.е. тебе не обязательно от каждой функции проверять ошибку она тебе там вернула или еще че то. Ты можешь просто там, где тебе нужно вызвать эту функцию и понять была ли ошибка до этого места или нет. Я давно на winapi не писал, но насколько я помню, любой успешный вызов системной функции занулит ошибку. Так что так сделать не получится - придется проверять каждый вызов. |
Сообщ.
#440
,
|
|
|
Цитата D_KEY @ Вот не надо так. То есть это нормально, если там действительно не всегда есть значение, то есть nullptr будет не ошибкой, а информацией об отсутствии значения и т.п. Если ошибка, то пусть лучше будет исключение. Тогда опять же можно будет использовать not_null. Мне вот в Kotlin нравится, что для nullable нужно явно ставить у типа ? А по умолчанию оно null быть не может. Ну так погоди, NETWORK_ERROR какой нибудь, тоже не будет ошибкой, а просто информацией что нет доступа к интернету. Добавлено Цитата OpenGL @ Зачем? Принесёшь хоть немного нетривиальный пример, тогда и перепишу. Этот же ничем не отличается от твоего первого примера с утечкой, после которого ты и приплёл RAII. Как зачем? Посмотреть как тру программист перепишет этот код, так как он считает нужным. В этом примере есть все, и ресурс, и операция, и ошибка. Какой тебе пример еще нужно? Так можно любой пример морозить. По поводу моего примера, перечитай как я его привел. А ? Давай его откинем и не будем его учитывать? Что бы у нас спор не ушел в сторону. Покажи как из сигнатуры функции следует, какие исключения она генерирует? Цитата OpenGL @ Потому что я не вижу причин, почему должно быть иначе. Ну а я вижу, потому что ты не обработаешь какое то исключение в этом месте, оно полетит выше, вылетит из метода обработчика, где то там даже может быть ты не забудешь его обработать, хрен с ним, и что в итоге получит код на каком нибудь JavaScript, который этот метод вызывал? Цитата OpenGL @ Цитата Так все верно, я его привел потому, что знал что ты будешь его приводить ![]() Тебе смешно, а это прямо было написано в моем посту, где я говорил про RAII. Ну а смех без причины, признак сам знаешь чего ![]() Цитата OpenGL @ Да нивапрос. Но раз мы не обсуждаем его, то не приплетай аргумент в духе "мы тут не можем бросить исключение потому что что-то испортится", приводя в качестве примера код, где проблема это отсутствие RAII а не исключение. Ты не понял что я от тебя хотел услышать, и до сих пор несешь чушь с умным видом. Да не в том дело обработаешь ты это исключение или нет. Я у тебя хочу выяснить, как ты будешь легко помнить какие исключения эта функция может кидать. А ты все никак не раскрываешь свой секрет. С кодами ошибок это сделать не сложно, достаточно структурировать эти самые коды ошибок. А с исключениями что делать то? Причем структурирование очень легко поддается рефакторингу, не нужно менять какие то там иерархии, переписывать в куче мест и т.п. А с исключениями как быть? У меня ведь именно к этому была претензия, а не к исключениям в целом. Цитата OpenGL @ И где тут выдирание из контекста? Речь ровно о том, с чего начался срачик - о том, что легко понять, какие исключения надо обрабатывать тут. Так покажи как ты понимаешь, какие исключения тебе кидает функция, так же легко, как например с кодами ошибок? Что ты все ходишь вокруг да около. Уже бы например привел сигнатуру функции со спецификацией исключений, и это уже был бы вменяемый ответ, и мы бы продвинулись дальше. А не то, что ты тут приводишь - "какие надо, такие и обрабатываю", "а какие надо?", "ну вот эти которые в этом месте нужно обработать". Цитата OpenGL @ Сигнатуру привести? А чего не имя разрабатываемого модуля, или день рождения жены соседа? Это всё к определению того, какие исключения надо будет обрабатывать, имеет ровно такое же отношение Ты понятия не подменяй. Не какое исключение обрабатывать, а: Цитата OpenGL @ помнить о том, что тут может броситься исключение не сложнее, чем помнить о том, что надо код возврата проверить. Вот ты например можешь сходу назвать какое/какие исключения кидает/не кидает например функция std::stoull ? И чего плохого в том, чтобы привести сигнатуру функции, и которой сразу видно, какие исключения она кидает. А иначе как еще проще, чем с кодами ошибок, понять что она может кидать? Не понимаю я тебя. Цитата OpenGL @ Ну да, тебе ответили "пусть летит". Привести реальный пример, когда бы оно всё сломало, ты так и не смог. Так значит ты его не споймал, значит не проще помнить, чем проверить код возврата. ![]() Добавлено Цитата D_KEY @ Я давно на winapi не писал, но насколько я помню, любой успешный вызов системной функции занулит ошибку. Так что так сделать не получится - придется проверять каждый вызов. Нет, не так. В основном функции вызывают SetLastError только когда произошла ошибка. Т.е. если функция завершилась успешно - ошибку она не занулит. Но есть некоторые функции, которые действительно могут перетереть ошибку, но в документации этих функций об этом явно написано. Добавлено https://docs.microsoft.com/ru-ru/windows/wi...pi-setlasterror Цитата Most functions call SetLastError or SetLastErrorEx only when they fail. However, some system functions call SetLastError or SetLastErrorEx under conditions of success; those cases are noted in each function's documentation. |
Сообщ.
#441
,
|
|
|
Цитата Wound @ Ну так погоди, NETWORK_ERROR какой нибудь, тоже не будет ошибкой, а просто информацией что нет доступа к интернету. Зависит от приложения. Цитата Нет, не так. В основном функции вызывают SetLastError только когда произошла ошибка. Т.е. если функция завершилась успешно - ошибку она не занулит. Но есть некоторые функции, которые действительно могут перетереть ошибку, но в документации этих функций об этом явно написано. Добавлено https://docs.microsoft.com/ru-ru/windows/wi...pi-setlasterror Цитата Most functions call SetLastError or SetLastErrorEx only when they fail. However, some system functions call SetLastError or SetLastErrorEx under conditions of success; those cases are noted in each function's documentation. Ну т.е. некоторые функции таки зануляют. Значит, твой паттерн в общем случае не применим. Кроме того, какой смысл вызывать какие-то еще функции, если у тебя уже случился фейл? Добавлено Цитата Wound @ Покажи как из сигнатуры функции следует, какие исключения она генерирует? Так это не нужно. Достаточно noexcept. В случае кодов возврата так же из сигнатуры не следует, какие коды генерирует функция ![]() |
Сообщ.
#442
,
|
|
|
Цитата D_KEY @ Ну т.е. некоторые функции таки зануляют. Значит, твой паттерн в общем случае не применим. Кроме того, какой смысл вызывать какие-то еще функции, если у тебя уже случился фейл? Ну если не читать документацию что делает функция, значит да, не применим мой паттерн. Но что тебе мешает сделать свою такую, которая не будет занулять. Я ж не говорю тебе используй SetLastError/GetLastError из WinAPi. Я тебе просто предложил подход, при котором, тебе не нужно будет писать мусорный код. И ты можешь проверять ошибку только тогда, когда тебе это действительно нужно, а не после вызова каждой функции. Цитата D_KEY @ Так это не нужно. Достаточно noexcept. В случае кодов возврата так же из сигнатуры не следует, какие коды генерирует функция Даа, и как, ты то я надеюсь каждую функцию, которая не кидает исключение помечаешь как noexcept ? Можно еще ради интереса взять какой нибудь опенсорсный проект и посчитать сколько раз там употребляется данный спецификатор. Вся фишка в том, что от того, что ты его не напишешь - ничего страшного не случится. В случае кодов возврата - смотря как ты это дело оформишь. Если же придерживаться какого то шаблона, и структурировать ошибки, то не составит труда разобраться какие коды ошибок может возвратить тебе функция. И параметры и возвращаемое значение функции - это не просто какой то спецификатор, который можно просто не написать, или лень будет писать. Это понимаешь как и с RAII. Можно его использовать и не парится, а можно не использовать и ловить исключения. Так и тут можно нафигачить совершенно непонятный код, где черт ногу сломит, и не важно коды возврата ты там будешь юзать или исключения. Но ты почему то, когда говоришь про исключения пишешь, что я вот тут все оберну в классы, используя RAII, вот тут это напишу, вот тут noexept помечу. А с кодами возврата я буду делать так, что ты ниче не разберешь где чего. Не понимаю я этот момент. |
![]() |
Сообщ.
#443
,
|
|
Цитата Wound @ Какой тебе пример еще нужно? Вот этот: Цитата Wound @ Это пример как раз тривиальной ситуации, когда нужно оборачивать. А бывают не тривиальные, когда не так очевидно что нужно оборачивать что то в классы, либо это попросту избыточно. Цитата Wound @ Ну а я вижу, потому что ты не обработаешь какое то исключение в этом месте, оно полетит выше, вылетит из метода обработчика, где то там даже может быть ты не забудешь его обработать, хрен с ним, и что в итоге получит код на каком нибудь JavaScript, который этот метод вызывал? Я не понимаю сути твоих вопросов. Если я это исключение поймал до его ухода в js, то что вернёт метод в js зависит от его реализации. Хочешь конкретику - давай конкретику со своей стороны. Цитата Wound @ Я у тебя хочу выяснить, как ты будешь легко помнить какие исключения эта функция может кидать. Что за тупые вопросы? А как ты помнишь, что тебе некую функцию foo надо заюзать вот в этом методе, а не в том? Цитата Wound @ Так значит ты его не споймал, значит не проще помнить, чем проверить код возврата. Или его просто не надо тут ловить. |
Сообщ.
#444
,
|
|
|
Цитата Wound @ Я тебе просто предложил подход, при котором, тебе не нужно будет писать мусорный код. И ты можешь проверять ошибку только тогда, когда тебе это действительно нужно, а не после вызова каждой функции. Но я не прерву тогда выполнение, что уже плохо, а иногда может привести и к ошибкам ![]() Добавлено Цитата Wound @ Даа, и как, ты то я надеюсь каждую функцию, которая не кидает исключение помечаешь как noexcept ? Если ее работа предполагает отсутствие исключений (а не просто так получилось на данный момент), то да, стараюсь. На текущей работе все стараются и на код ревью это тоже смотрим. Но вообще если не уверен, то считай, что функция может кинуть исключение. Никаких проблем с этим нет. Добавлено Цитата Wound @ А с кодами возврата я буду делать так, что ты ниче не разберешь где чего. Не понимаю я этот момент. Как бы ты хорошо не писал код, при использовании кодов возврата у тебя будет мусорный код с проверками на каждый чих. Одно из достоинств исключений - это как раз отделение кода обработки ошибок от логики. Добавлено А если ошибки являются частью логики, то да, лучше использовать option и result. Но опять же, не коды возврата. Одна из разумных причин хейтить go как раз заключается в том, что язык в 21 веке тащит за собой столь примитивный подход к обработке ошибок. Из 60-70х годов прошлого века. |
Сообщ.
#445
,
|
|
|
Цитата OpenGL @ Вот этот: Ну так я тебе и привел нетривиальный пример, чтоб ты написал как ты это сделаешь, если тебе нужно это вызвать буквально в паре мест. Что тебя смущает то? Цитата OpenGL @ Я не понимаю сути твоих вопросов. Если я это исключение поймал до его ухода в js, то что вернёт метод в js зависит от его реализации. Хочешь конкретику - давай конкретику со своей стороны. Ну как не понимаешь то? Например есть у тебя метод: ![]() ![]() //! Route: api/mycontroller/SomeMethod ISomeInterface* PostSomeMethod(const SomeDataStruct& data) { //! Тут какая то логика, например там добавление пользователя в базу данных, да что угодно, и возвращение результата неважно какого, допустим это какая то структура } //! Route: api/mycontroller/SomeMethod ISomeInterface* GetSomeMethod(const string& id, int someParam ) { //! Тут какая то логика, например там вычитка чего то из откуда то и возвращение результата } Дальше у тебя эти методы где то там в вебсервисе висят в качестве обработчиков, естественно они обернуты всякими там try/catch ни одно исключение не пролетит. Дальше ты из JavaScript например хочешь что то запостить там: ![]() ![]() $.ajax({ type: 'POST', url: BaseUrl + "/api/mycontroller/somemethod", data: SomeData, dataType: "json", success: function (response) { /*Вот тут твой результат*/ }, failure: function (error) { /*тут ошибка выполнения аякса*/ } }); } Вся фишка в том, что если у тебя произойдет исключение внутри эти методов, и ты это исключение не поймаешь в этих методах, то JS у тебя просто не получит нужный ему ответ. А исключение выше у тебя да обработается. Только толку от этой обработки то? Цитата OpenGL @ Что за тупые вопросы? А как ты помнишь, что тебе некую функцию foo надо заюзать вот в этом методе, а не в том? Эээм, да как тупые вопросы то, ты ж пишешь что помнить какие исключения генерит функция не сложнее чем с кодами возврата. Вот я у тебя и спрашиваю каким образом? Если бы они были неотъемлемой частью сигнатуры функции, тогда тут да, не поспоришь. В противном случае ответом может разве что быть оборачивать все в try/catch(...). Но ведь это излишество, тогда это примерно тоже самое что и с проверкой кодов возврата. Цитата OpenGL @ Или его просто не надо тут ловить. Ну а зачем тогда вообще что то ловить? Можно в функции main все обернуть try/catch(...) и все, нет проблем ![]() |
Сообщ.
#446
,
|
|
|
Цитата Wound @ Цитата OpenGL @ Или его просто не надо тут ловить. Ну а зачем тогда вообще что то ловить? Можно в функции main все обернуть try/catch(...) и все, нет проблем ![]() Зачем крайности? Как правило очень многие вещи действительно нет смысла ловить на данном уровне. |
Сообщ.
#447
,
|
|
|
Цитата D_KEY @ Но я не прерву тогда выполнение, что уже плохо, а иногда может привести и к ошибкам Ты его и с исключениями не прервешь в таком случае. Разницы особой нет. Ну вот работаешь ты с WIN API, вон читаешь значение из реестра, настройку какую то. А у тебя функция возвращает ошибку - access denied к ветке реестра, которую ты пытаешься дернуть. И как ты без проверки кинешь исключение? ![]() Или ты мне рассказываешь про случай, когда за тебя уже все проверки сделали и код написали, и исключения все покидали, а ты только вызываешь эту функцию и ловишь? Эка ты какой шустрый ![]() Цитата D_KEY @ Если ее работа предполагает отсутствие исключений (а не просто так получилось на данный момент), то да, стараюсь. На текущей работе все стараются и на код ревью это тоже смотрим. Но вообще если не уверен, то считай, что функция может кинуть исключение. Никаких проблем с этим нет. Ну стараешься - это же не строго следуешь ![]() Цитата D_KEY @ Как бы ты хорошо не писал код, при использовании кодов возврата у тебя будет мусорный код с проверками на каждый чих. Одно из достоинств исключений - это как раз отделение кода обработки ошибок от логики. Я с тобой не соглашусь. И тут уже можно привести в качестве аргумента того же Линуса Торвальдса. Например натыкался на статью на хабре, где чувак приводил примеры Линуса с презентации, и речь шла про правила хорошего вкуса. И приводился пример для рассмотрения, на котором Линус показывал что он имеет ввиду. В частности был приведен вот такой кусок кода(в спойлере): Скрытый текст ![]() Данный кусок кода - показывает как сделают большинство программистов. Но с точки зрения Линуса - этот код без вкуса. И привел пример, как переписать этот пример лучше: Скрытый текст попробуй сам улучшить пример выше ![]() Попробуй подумать и улучшить пример из первого спойлера, а уж потом заглядывай во второй, если тебе это интересно будет. Так вот разный подход к решению одной задачи. И я лично вот тоже задумался, есть привычные шаблоны, по которым ты действуешь. А есть нестандартные решения, которые более лучше. Вот примерно так с кодами возврата. Можно сидеть и думать что у тебя с кодами возврата будет мусорный код всегда, и юзать исключения. А можно просто юзать коды возврата, и не испытывать тех проблем, о которых ты пишешь. Хотя повторюсь, лично я не говорю что коды возврата лучше, или исключения лучше. По мне - что одни, что вторые имеют свои достоинства и недостатки. Лично я использую и то и другое. И у меня нет какой то ненависти к исключениям или кодам возврата. Если интересна сама статья про которую я выше написал, можешь посмотреть ее тут: Скрытый текст |
Сообщ.
#448
,
|
|
|
Цитата Wound @ Цитата D_KEY @ Но я не прерву тогда выполнение, что уже плохо, а иногда может привести и к ошибкам Ты его и с исключениями не прервешь в таком случае. Как не прерву? Выброс исключения сам все прервет. Цитата Ну вот работаешь ты с WIN API, вон читаешь значение из реестра, настройку какую то. Я не буду так делать. Я или возьму чужую обертку или напишу свою. Цитата А у тебя функция возвращает ошибку - access denied к ветке реестра, которую ты пытаешься дернуть. И как ты без проверки кинешь исключение? ![]() В обертке(чужой или моей) это будет сделано один раз. Затем уже будет нормальные исключения. Цитата Ну стараешься - это же не строго следуешь ![]() Ну если там не будет noexcept, значит будет считаться, что функция может кидать исключения. Ничего страшного. Цитата Так же тебе любой Сишник, который юзает коды возврата расскажет, что в их проекте нет проблем, котоыре ты тут выдумываешь про коды возврата, потому что они следуют своему стандарту. И у них и в правду не будет тех проблем, о которых вы тут пишете. Код проверки на каждый вызов писать придется все равно. Цитата Цитата D_KEY @ Как бы ты хорошо не писал код, при использовании кодов возврата у тебя будет мусорный код с проверками на каждый чих. Одно из достоинств исключений - это как раз отделение кода обработки ошибок от логики. Я с тобой не соглашусь. И тут уже можно привести в качестве аргумента того же Линуса Торвальдса. Например натыкался на статью на хабре, где чувак приводил примеры Линуса с презентации, и речь шла про правила хорошего вкуса. И приводился пример для рассмотрения, на котором Линус показывал что он имеет ввиду. В частности был приведен вот такой кусок кода(в спойлере): Скрытый текст ![]() К чему это? Там нет вызовов и проверок, соответственно. Цитата Данный кусок кода - показывает как сделают большинство программистов. Но с точки зрения Линуса - этот код без вкуса. И привел пример, как переписать этот пример лучше: Скрытый текст попробуй сам улучшить пример выше ![]() Попробуй подумать и улучшить пример из первого спойлера, а уж потом заглядывай во второй, если тебе это интересно будет. Ок, потом посмотрю, спасибо. Цитата А можно просто юзать коды возврата, и не испытывать тех проблем, о которых ты пишешь. Как их можно не испытывать? Я даже когда тебе пример писал, для третьего if'а я уже не выдержал этой копипасты и мне стало неприятно. А это, блин, тестовый пример. |
![]() |
Сообщ.
#449
,
|
|
Замечательная правка. Теперь код сложнее понимать, а ошибка так и не устранена.
|
Сообщ.
#450
,
|
|
|
Цитата Wound @ Эта функция не возвращает никаких ошибок. Возьми например абстрактно посмотри на сигнатуру функции: bool is_open(); Да мне ничего не нужно делать, чтоб понять какие ошибки эта функция может возвратить. либо true, либо false. ![]() |