Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.100.234] |
|
Страницы: (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 . Т.е. тебе не обязательно от каждой функции проверять ошибку она тебе там вернула или еще че то. Ты можешь просто там, где тебе нужно вызвать эту функцию и понять была ли ошибка до этого места или нет. Если нет - значит делай свою следующую операцию, если была - возвращай ошибку, или обрабатывай ее. |
Сообщ.
#437
,
|
|
|
Цитата 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. |