вторник, 1 января 2030 г.

О блоге

Более двадцати лет я занимался разработкой ПО, в основном как программист и тим-лид, а в 2012-2014гг как руководитель департамента разработки и внедрения ПО в компании Интервэйл (подробнее на LinkedIn). В настоящее время занимаюсь развитием компании по разработке ПО stiffstream, в которой являюсь одним из соучредителей. Поэтому в моем блоге много заметок о работе, в частности о программировании и компьютерах, а так же об управлении.

Так же я пишу о жизни вообще и о нескольких своих увлечениях: о фотографии (включая публикацию своих фотографий, некоторые есть и на ZeissImages), о спорте, особенно о дартсе, и, совсем коротко, о кино.

понедельник, 31 декабря 2029 г.

[life.photo] Характерный портрет: вы и ваш мир моими глазами. Безвозмездно :)

Вы художник? Бармен или музыкант? Или, может быть, коллекционер? Плотник или столяр? Кузнец или слесарь? Владеете маленьким магазинчиком или управляете большим производством? Реставрируете старинные часы или просто починяете примус? Всю жизнь занимаетесь своим любимым делом и хотели бы иметь фото на память?

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

пятница, 20 января 2023 г.

[prog.flame] И долго в Boost будут тащить все, что не попадя?

На включение в Boost претендует библиотека Aedis, ревью идет прямо сейчас. Aedis -- это написанный на Asio клиент для Redis-а.

Определенно нужная для кого-то вещь, спору нет. Автору библиотеки респект и уважуха на полном серьезе. Так что у меня нет никаких сомнений о нужности Aedis-а вообще.

Зато есть вопрос "А что сейчас есть Boost и зачем он нужен?"

Как бы в нулевых предназначение Boost было понятно. Типа полигон для новых идей, чтобы затем добавлять в язык то, что уже было проверено на практике. Попавшие в стандарт через Boost умные указатели, хэш-таблицы и регулярные выражения тому подтверждение.

Но клиент для Redis-а?

Его что, кто-то хочет видеть в стандартной библиотеке C++? Серьезно?

А раз нет, то какой смысл развивать Boost как сборище всякого разного и разнообразного? Зачем весь этот винегрет держать под одной крышей?

Простите мне мой цинизм, но я вижу в этом всего лишь одну цель: паразитирование на известности Boost-а.

Вот жила-была себе библиотека, мало кто про нее знал. А тут она раз, и в Boost-е. И, поскольку множество C++ников выросло на принципе "если что-то нужно, то посмотри сперва в Boost", то как раз такие C++ники посмотрят сперва в Boost, возьмут оттуда первую попавшуюся и не будут больше ничего искать.

Boost уже сейчас скопище из более сотни (если не ошибаюсь) библиотек. Причем даже с некоторым дублированием (сколько там сейчас библиотек для работы с конечными автоматами? сколько для парсинга?). Сам по себе вопрос "А вы знаете Boost?", который был актуальным году в 2005-ом, сейчас уже потерял смысл. А человека, который ответит на него "Да" мне будет сложно воспринимать всерьез.

Может быть включение в Boost гарантирует то, что авторов библиотек будут финансировать? Или есть гарантия, что библиотеку автоматически подхватят, когда первоначальный автор перестанет ей заниматься?

И ладно бы Boost задавал какую-то недостижимую планку качества, а библиотеки оттуда не имели бы никаких вменяемых альтернатив за пределами Boost-а.

Так ведь нет.

Какие-нибудь Catch2 или doctest могут быть намного более простыми и удобными альтернативами Boost.Test. А spdlog может быть удобнее и практичнее, чем Boost.Logging. А fmtlib чем Boost.Format.

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

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

Но нет, Boost продолжает вбирать в себя всякую всячину.


PS. Из личного: убежден, что если бы Beast не протолкнули бы в Boost, то ее популярность в C++ мире была бы сильно ниже. Впрочем, если кто-то взял в проект Boost.Beast просто потому, что "это же из Boost-а", то что тут остается сказать? Разве что "полной ложкой, говорю, черпай!"

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

четверг, 19 января 2023 г.

[prog.wow] Это настолько прекрасно про "маргинальщину", что невозможно не утащить в анналы :)

Найдено на RSDN. Такой сгусток боли невозможно не утащить в склерозник, ибо вряд ли когда-нибудь еще встретится столь мощно сформулированное:

IMHO, упоминание маргинальщины (D, Haskel, Erlang, SVN, FreeBSD) — это диагноз. Разумные люди от нее избавляются и переходят на более популярные инструменты, потому что так удобнее. С маргинальщиной живут только полные фанатики. И параноики, которым постоянно кажется, что D — центр вселенной и оттуда кто-то что-то тырит. Работают такие фанатики исключительно в одиночку. Ни один разумный человек с маргинальщиной работать не будет, даже при зарплате в разы выше рынка.

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

суббота, 14 января 2023 г.

[prog.flame] Знания фреймворков, полезные и бесполезные...

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


Итак, вещь первая: при смене фреймворка знания предыдущего фреймворка оказываются бесполезными. Например, опыт в MFC окажется бесполезным при работе с Qt, опыт работы с Qt окажется бесполезным при работе с Asio, опыт с Asio окажется бесполезным при работе с FFMPEG и т.д., и т.п.

Да, столь резкая смена (Qt на Asio и Asio на FFMPEG) запросто возможна при смене предметной области.

вторник, 10 января 2023 г.

[work.thoughts] Внутренние фреймворки -- проблема для маленьких компаний?

В одной из дискуссий на RSDN был задан вопрос:

Бывало ли в вашей практике, что компания завязывала людей на собственные разработки, которые больше нигде не используются?

В связи с этим мне вот что подумалось: а ведь внутренний фреймворк X от компании "Рога и Ко" -- это же совсем не проблема для больших компаний. Ну, типа никого же из тех, кто стремится попасть в Google, Facebook или Яндекс не волнует то, что там придется работать с внутренними разработками компаний, которые нигде больше не используются (за исключением случаев, когда крупная компания выложила что-то в OpenSource).

Это для маленьких и средних компаний использование какой-то собственной внутренней технологии может быть проблемой: на рынке готовых специалистов, знакомых с этой технологией нет, имеющиеся на рынке кадры могут не захотеть идти на эту технологию (потому что потом этот опыт не пригодится), а если захотят, то попросят большую зарплату. Да и потом такие уникальные сотрудники будут неким "элементом неустойчивости" -- стоит паре-тройке ключевых разработчиков уйти, и "Рога и Ко" могут оказаться в весьма тяжелом положении, ведь продукт, который постоянно используется, нуждается в постоянном сопровождении (иногда больше, иногда меньше, но все-таки без присмотра не оставишь). Сопровождать нужно, а некому. И нет толпы страждущих соискателей, как на пороге Google или Яндекса.

Вот такая вот мысль. Внезапно, что называется.

И одно из следствий. Маленьким компаниям, если они используют собственные разработки, на рынке труда придется вести себя не так, как могут позволить себе крупные.

Это, в принципе, и так понятно. Но одно дело, когда компания ищет разработчиков со знанием каких-то общепризнанных инструментов (вроде Qt для C++). И совсем другое, когда у компаний какой-то свой условный userver, про который никто снаружи "Рога и Ко" даже и не знает.

среда, 4 января 2023 г.

[prog.c++] Всегда ли выброс исключения из noexcept функции является ошибкой?

На написание этой заметки подтолкнула статья "Топ-10 ошибок в C++ проектах за 2022 год", а если точнее, то ошибка, которая там поставлена на шестое место. В двух словах: в операторе перемещения некого класса вызывается метод setName, в котором может быть брошено исключение. При этом сам оператор перемещения помечен как noexcept.

На мой взгляд, ситуация здесь не так проста, как может показаться.

И дело в том, что некоторые C++ программисты (включая меня самого в прошлом) смотрят на маркер noexcept (не бросает) как на маркер nofail (не сбоит, всегда OK). Т.е., если у нас есть noexcept-функция, то она не может завершиться с ошибкой.

В каких-то случаях так оно и есть. Например, если мы делаем swap для двух int-ов или для двух обычных указателей, то странно ожидать появление ошибки в таком swap.

Однако, noexcept означает nofail далеко не всегда.

Зато noexcept всегда означает norecover (если сбоит то без шансов на продолжение). Т.е., если в noexcept функции что-то пошло не так, то восстановиться до какого-то вменяемого состояния у нас уже нет возможности.

К сожалению, в C++ nofail от norecover не отличимы. Мы можем написать только noexcept, но не можем дать дополнительной информации: гарантируем ли мы отсутствие ошибок или же лишь подтверждаем, что при возникновении ошибки восстановление невозможно и единственный разумный путь -- это std::terminate.

И если рассматривать noexcept именно как norecover, то вызовы бросающих исключение функций в noexcept-функциях становятся вполне себе оправданными. Какой смысл оборачивать бросающие функции в try..catch чтобы в catch самому вызвать std::abort? Сам по себе noexcept сделает это не хуже нас.

В общем, я постепенно пришел к тому, чтобы рассматривать noexcept-функции прежде всего как norecover-функции. И только в некоторых, чаще всего в тривиальных случаях, как nofail-функции.

А посему теперь спокойно отношусь и к тому, что в noexcept-функция могут запросто вызываться бросающие исключения функции без оборачивания их в try..catch. И не считаю такое поведение ошибкой.

Но здесь вновь нужно сказать, что лично мне очень сильно не хватает в C++ noexcept-блока. Пишешь такой блок, а компилятор выдает предупреждение, если внутри noexcept-блока вызываются не-noexcept-функции.

Полезно такое иметь потому, что:

  • человеку свойственно ошибаться и я могу думать, что вызванная мной функция f() является noexcept, а на самом деле нет;
  • все течет, все изменяется. Изначально f() могла быть noexcept, но со временем ее могли модифицировать и убрать маркер noexcept. Но я, как пользователь f(), об этом даже не узнаю.

Не думаю, однако, что когда-нибудь в C++ noexcept-блок появится.

Да и вообще, глядя на то, что подобавляли в C++20 (например, модули, в которые без поллитры не въедешь) и в C++23 (например, deducing this), все больше и больше прихожу к заключению, что я недостаточно умен, чтобы освоить настолько сложный инструмент :(

PS. Возвращаясь к упомянутой выше статье. Думаю, что предложенные автором статьи способы исправления обнаруженной анализатором "ошибки", мягко говоря, неуместны. Там нужно было копать совсем в другую сторону (а то и в несколько разных сторон).