Pull to refresh
1
0

User

Send message
Вы, кажется, как и Goodkat, считаете, что США

Вам, действительно, кажется. Я прокомментировал конкретное число для конкретной страны, поскольку для неё были приведены данные. Ситуация в мире — это даже не общая температура по больнице, а сферический конь в безвоздушном пространстве, так как нет единой методологии учёта. Имеет смысл рассматривать в пределах конкретной страны до те пор пока не закончилось и можно кое-как посчитать в мире.


К слову, мой комментарий тоже не до конца корректен, так как распределение не равномерное, и мне ничего не известно про количество смертей от гриппа в пик сезона (может быть больше тысячи в день, но скорее нет). Если смерти продолжатся ещё с неделю и достигнут 16к, то тогда уже можно смело сказать, что в США смертность при всех принимаемых мерах больше, чем от гриппа. Медицинская система США базово далеко не самая лучшая, но тем не менее и не самая худшая. А значит волноваться стоит странам с худшей системой здравоохранения или схожей структурой медицины.


На вопросы "почему — не паниковали от гриппа, а сейчас паникуют" мой ответ: потому что неизвестное и непонятное, в отличие от гриппа. Является ли меры полностью и везде адекватным — нет, адекватно было только в Южной Корее, как мне кажется. Спасло бы мир от рецессии в 2020-2021, если бы не было локдауна — нет.

не спору ради, но для большей корректности:


61000 человек от гриппа за год — это 167 человек в сутки.

Грипп — сезонное заболевание, в северном полушарии сезон классически с ноября по март. То есть на 365 делить не совсем корректно. Ближе 350-670/сутки при сезоне длиной квартал-полугодие. Что, впрочем, тоже в разы меньше, чем текущие показатели коронавируса, которые продолжают расти.

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

Проблема, конечно, чаще всего связана с насильственным внедрением; наличием ADD практик в компании; неверным выбором скрама в качестве методологии, которая сделает всем хорошо; упованием на волшебный авось и ту самую кривую, что путем коротких итераций и рестроспектив выведет на устойчивую орбиту эффективного зарабатывания бабла. Скрам зачастую не подходит. Компании, их клиенты/стейкхолдеры и область деятельности, требования к доставке — разные. Это стоит признать, а не продолжать насаждать карго-культ и поедать кактус на скорость.

Имел возможность наблюдать исход людей, подвергнутых испытанию скрамом. Видел утрату технической компетенции в команде. Отношусь к этой методологии скептически.
Я считаю, что кривой драйвер — это проблема драйвера, которая к программе не относится. Поэтому обрабатывать ошибки драйвера, тем более которые невозможно обработать в юзерспейсе, программа не должна пытаться.

Утомился писать в этой теме, да ещё и не по теме. Поэтому пойду в какую-нибудь другую.
Так вы ругаетесь на документацию, в которой не написано про краши при вызове open() или нет? Или на то, что драйвер, например, в uninterruptable sleep и ваше приложение невозможно ни убить, ни отладить по этой причине?

Думается мне, нет. Вот так же и с тем самым невозвращением nullptr.
Ожидаемое потому, что исключения запрещены в коде, код собирается с соответствующими параметрами. Про документацию выше в этой ветке написано.

Если то, что про документацию написано, не удовлетворяет, то вот взгляд с другого угла: с точки зрения программы исчерпание памяти — это системная проблема.
Когда приложение крашится из-за проблемы в оборудовании, вас же не волнует почему системный вызов open() не вернул ничего, и приложение скрашилось? Теперь распространите это на случай обсуждаемой функции.

Если и этот угол не нравится, то что ж, се ля ви. Это, впрочем, никак не влияет на факт того, что исключения отключены в llvm, это никак ему не мешает, а использованная конструкция new в связке с проверкой на nullptr вполне себе имеет смысл.
Почему приложение будет закрыто?

Потому что такова общепринятая реализация: вызов terminate() и в нем стандартным обработчиком является abort().

Как стандартная библиотека вообще увидит что ее вызвал код без поддержки исключений?

Не верьте мне на слово, просто возьмите наскоро написанный код да и проверьте: http://pastebin.com/FtigcuwJ

Подробности про почему ищите по ключевым словам __cxa_throw и Itanium C++ ABI.
Суть в том, что если происходит ошибка при развертывании стека, то вызовется terminate().

Кстати, внезапное закрытие приложения — это, по-вашему, правильное поведение?

Зависит от приложения и обстоятельств.
В случае с llvm — это ожидаемое поведение, т.к. исключения приходить в него не должны, так задумано, документировано и прочая. Кроме того, нет ничего более действенного для отладки приложений, чем краши, да ещё и с крашдампами. Культура stop to fix сразу начинает развиваться сама собой.
Если у нас есть внешний код A (с поддержкой исключений), библиотека B (без поддержки) и стандартная библиотека с поддержкой, то утечки не будет, так как приложение будет закрыто — и утекать нечему будет.

Чтобы исключение было поймано внешним кодом в А, нужно чтобы и B было собрано с соответствующей поддержкой. Но в таком случае, никакой утечки ресурсов, которыми владеют unique_ptr, не будет.
> Когда оно будет поймано внешним кодом — ресурсы, удерживаемые локальными unique_ptr, утекут.
Изложите мысль подробнее, пожалуйста. С утра прочитаю, на ночь глядя тяжело понять, почему вы считаете, что деаллокаторы unique_ptr не будут вызваны при раскрутке стека.
Не забывайте про утечку памяти из-за невызванных деструкторов локальных переменных.

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

Если же речь идёт уже безотносительно к обсуждаемому проекту, то бишь в общем и целом о полезности раскрутки стека при исключениях: кто ж спорит с тем, что базово оно полезно за исключением ряда областей применения ПО, а при правильном применении ещё более полезно?

то разработчик библиотеки смотрит на описание метода и видит, что при ошибке метод вернет nullptr.

В отличие от некоторых других языков, отсутствие указания на то, что метод может кинуть исключение, в С++ не означает того, что не может такого быть в принципе. nullptr вполне может быть и корректным возвращаемым значением, а не суррогатным статусом ошибки, но при этом возможны исключительные ситуации, которые имеет смысл отлавливать и централизовано обрабатывать. Автор промежуточной библиотеки гарантировать конечному пользователю ничего не может за пределами своей зоны ответственности, т.к. исключительная ситуация может возникнуть в нижележащем коде, о поведении которого бессмысленно строить предположения.

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

Но есть несколько аргументов против nothrow варианта. Основным является таковой: если этот код используется в составе библиотеки, используемой сторонними утилитами (что нередко происходит с кодом llvm), то это поломает схему обработки исключений в них, сотворив франкенштейна, в котором часть исключений будет обрабатываться, а часть не будет, так как будет явным образом замкнуто на локальную обработку по месту возникновения ошибки выделения памяти.

Кроме того, обычно nothrow вариант напрямую вызывает «throw» вариант, то есть фактически является оберткой вокруг кидающего исключения operator new. По сути это добавляет лишний вызов, если стандартная библиотека собрана без поддержки исключений.

Вполне себе аргументы, на мой взгляд, которые позволяют сказать, что утверждение «Этот код не имеет смысла, так как если память не удастся выделить, должно быть сгенерировано исключение std::bad_alloc» не является в контексте конкретного проекта абсолютно корректным.
Ответ ниже. Промахнулся на телефоне мимо ссылки.
До того, как мы углубимся в дебри разборок в том, кто и что понимает, давайте рассмотрим две ситуации:
1. llvm собранный без поддержки исключений, и libc++/libstd++, собранные с их поддержкой. В обсуждаемом месте будет abort(). Некрасиво? Пожалуй так, но это ожидаемое и задокументированное поведение для проекта.
2. Оба без поддержки. Ситуация невыделения памяти как-то относительно корректно обработана.

Вы утверждаете, что 1) недопустимо для проекта, не спросив в общем-то их мнения. Я так понимаю, что и Страустроп с его стародавним демаршем в отношении исключений в jsf++ не аргумент, если необходимо гнаться за мифом о кросс-платформенности.

Тем не менее отловить исключение там невозможно, т.к. llvm собран без соответствующей поддержки. Если убрать условие — все равно будет abort() в 1), но теперь ещё и 2) будет обрабатываться некорректно. Предупреждение показывать на данном примере бессмысленно, т.к. архитектурное решение (отказ от использования исключений) не позволяет устранить потенциальный аварийный выход. Более того, фанатичное следование предложенному решению (убрать условие), уничтожает обработку ошибки. То есть программа станет не лучше, а хуже.

Об этом был мой комментарий, который был направлен на улучшение статьи путем добавления одной маленькой ремарки. Статья не о стандартах С++, а о статическом анализаторе и как он помогает находить дефекты. Обсуждаемое — это false positive в силу специфики проекта. То есть по факту показывает слабые стороны статического анализа, что на мой взгляд не входило в задачи статьи.

Ну а теперь давайте продолжим кидаться какашками и гадать на кириллице, кто и как видит разницу между чем.
В случае llvm это не просто кодинг стайл, это принципиальное архитектурное решение, выбранное разработчиками проекта. Достаточно нетрудно увидеть где в AddLLVM.cmake появляется -fno-exceptions. Ну и для полноты картины можно заглянуть в ту же libc++ реализацию operator new и увидеть как легко и непринужденно эта самая поддержка исключений отключается с помощью магии макросов.

По ссылке — объяснение почему конкретно llvm не использует исключения. Оную поддержку часто отключают и при разработке встраиваемых решений. Раньше отключали и на консолях, теперь это менее актуально (хотя если мне не изменяет память даже в последнем SCE SDK llvm тулчейн форсирует -fno-exceptions и библиотеки собраны без поддержки исключений).

Что касается вываливаний: нет throw — нет и abort().
Этот код не имеет смысла, так как если память не удастся выделить, должно быть сгенерировано исключение std::bad_alloc.

В кодобазе LLVM же запрещено использовать RTTI и исключения. Так что можно смело в статью добавить «но к LLVM это не относится, ибо тут так заведено.» и ссылку на стандарт кодирования llvm.

А вообще полезная проверка. Почивший в бозе cppcat нашел несколько таких в моих хобби-проектах и мне было даже немного стыдно, но потом прошло.

Information

Rating
Does not participate
Registered
Activity