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

О блоге

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

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

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

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

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

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

понедельник, 1 июня 2026 г.

[prog.c++] Попробовал познакомиться с модулями C++20 и чего-то недопонял

Провел пару простых экспериментов с модулями C++20 и получил странные результаты.

Эксперименты проводились под Windows с VS2022 и VS2026 (обновления от мая 2026-го) и ArchLinux с GCC 16.1 и clang 22.1.

Ожидаемые мной результаты (т.е. отсутствие проблем компиляции/линковки) получились только с clang 22.1 и libc++. А вот с GCC и VC++ случились какие-то проблемы, которые мне сложно объяснить.

Во всех случаях сборка осуществлялась через CMake и Ninja.

Исходные коды описанных ниже тестовых программ можно найти в этом репозитории.


Эксперимент первый (case_001 из упомянутого репозитория). Очень простой модуль. Декларация в файле hello.ixx:

[life.cinema] Очередной кинообзор (2026/05)

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

Фильмы

Полный Такос (Operation Taco Gary's, 2026). Совершенно укуренный и классный фильм. Мне зашел, но из-за его специфичности рекомендовать не могу -- наверняка понравится не всем. Однако, хороший пример того как за дешево можно снять приличную юмористическую фантастику.

Эдем (Eden, 2024). Хорошая история, хорошая операторская работа, отличная игра актеров. Но вот рассказана эта история так, что не особо и цепляет. Поэтому самые сильные впечатления производят реальные фотографии и кадры хроники, показанные в самом-самом конце.

Они убьют тебя (They Will Kill You, 2026). Неплохая черная комедия в стиле фэнтези с реками крови и грудами отрубленных конечностей.

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

Нормал (Normal, 2025). Не понял что это было: для комедии вроде бы слишком нудный, для боевика слишком комедийный. Посмотреть можно, но лучше ничего особенного не ждать.

Сезон охоты ("Blood of Man" или "Hunting Season", или "Mermaid", 2025). Добротно, но слишком уж неторопливо и маловато экшОна. По сути, весь фильм держится на харизме Мэла Гибсона.

Мумия ("The Mummy" или "Lee Cronin's The Mummy", 2026). Для своего жанра, в принципе, нормально. Но манера съемки у фильма такая, что воспринимается это все как театральная постановка и поэтому погружения в атмосферу ужаса не происходит.

Охота ("Hunt" или "Heon-teu" или "헌트", 2022). Есть русский бунт, бессмысленный и беспощадный. А есть корейские боевики, не менее бессмысленные и беспощадные 🙂 А если для вас все корейцы на одно лицо и их имена вы не запоминаете вообще, то следить за логикой происходящего на экране будет совсем сложно.

Мститель (Protector, 2025). Что будет, если смешать "Рембо", "Заложницу" и "Джона Уика" в очень-очень бюджетном кино, да еще и с типа крутой теткой в главной роли? А вот унылое говно под названием "Мститель" и получится.

Пастбища богов (2025). Местами красивые пейзажи. Пожалуй, это единственное, что есть хорошего в данном "кино".

Сериалы

Пацаны (The Boys, пятый сезон, 2026). Самый слабый из все сезонов. Но если предыдущие понравились, то надо смотреть хотя бы для того, чтобы увидеть чем все закончилось.

Отпечатки (первый сезон, 2025). Пока смотришь -- интересно, да и главного злодея хорошо замаскировали до самой последней серии, за что авторам респект. Но вот когда начинаешь задаваться вопросами как же такое могло происходить, то возникает устойчивое ощущение, что нам втирали какую-то дичь. Так что по итогу остались негативные впечатления.

Гнев (Man on Fire, первый сезон, 2026). Первые серии бодренькие, затем какие-то тягомотные сопли, а в финале какой-то сплошной маразм. Так что можно смело пройти мимо.

вторник, 26 мая 2026 г.

[prog.c++.bugs] Похоже наткнулся на баг в GCC 12/13 под Linux-ом. Или нет.

Дело было так: есть некий объемный и сложный шаблон класса-контейнера. Для тестирования было создано приложение с юнит-тестами на базе Google.Test. В состав этого приложения входит порядка 30 (тридцати) .cpp-файлов. В некоторых из них происходит следующее:

namespace
{

template<typename T>
struct test_traits : public my_container::default_traits<T> {
  static constexpr std::size_t key_size = 3;
};

/* namespace anonymous */

TEST(my_container, some_test)
{
  my_container::my_map<int, test_traits> map;
  ... // какие-то действия с map.
}

Т.е. суть в том, что в десятке .cpp-файлов есть анонимные пространства имен, в каждом из которых определяется шаблон класса с именем test_traits. Затем этот шаблон используется для инстанцирования класса-контейнера.

Все это работало до тех пор, пока не был добавлен еще один .cpp-файл, в котором было практически тоже самое:

namespace
{

template<typename T>
struct test_traits : public my_container::default_traits<T> {
  static constexpr std::size_t key_size = 3;
  static constexpr my_container::mode use_mode =
      my_container::mode::versioned;
};

/* namespace anonymous */

TEST(my_container, some_test_versioned)
{
  my_container::my_map<int, test_traits> map;
  ... // какие-то действия с map.
}

И вот тут-то в some_test_versioned с map стали происходит странные вещи: возникали segmentation faults там, где их быть не должно было. Попытки отладить код приводили к тому, что отладчик показывал, что отрабатывают не те ветки if-ов. А отладочные печати содержали совсем не те значения, которые должны были бы быть.

Было полное ощущение, что GCC сошел с ума.

Проект, в рамках которого все это делается, собирается VC++ под Windows и GCC под Linux-ом. Под Linux-ами используются GCC 12 и 13. Конкретно я работаю с GCC 13, но проверил и под GCC 12. Сам проект уже не очень маленький, плюс подтягивает кучу зависимостей разного калибра (включая Folly и Abseil). Все это к тому, что мероприятие по перекомпиляции проекта под какой-то свежий GCC или clang -- это попытка с негарантированным результатом. Может повезти, а может и нет.

Под Windows проверил, там ничего подобного нет, все работает как и положено. А вот под Linux-овым GCC -- проблемы.

В итоге подумал о том, что GCC воспринимает все мои test_traits как нарушение ODR и я наступаю на грабли UB. Поэтому переименовал test_traits так, чтобы во всех .cpp-файлах имена оказались уникальными, даже не смотря на то, что живут они в анонимных пространствах имен.

После этого все описанные выше магические проблемы разом исчезли.

Есть у меня сильное подозрение, что это таки был баг в GCC. Поскольку, если мне не изменяет склероз, все, что определяется внутри анонимного пространство имен, должно быть абсолютно уникальным. В том числе это касается и шаблонов.

Но на 100% не уверен. Может быть здесь дело еще и в том, что у my_container::map есть шаблонный параметр шаблона, т.е.:

namespace my_container
{

template<typename T, template<typenameclass Traits>
class map { ... };

/* namespace my_container */

Поэтому его параметризация в тесте идет не конкретными типами, а шаблоном:

TEST(my_container, some_test_versioned)
{
  my_container::my_map<
    int// Это конкретный тип.
    test_traits // А это шаблон, который развернется в конкретный
                // тип уже внутри map.
  > map;
  ... // какие-то действия с map.
}

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

четверг, 21 мая 2026 г.

[prog.c++] Обнаружился баг в timertt возрастом более 10 лет

Пользователи обнаружили в SObjectizer проблему, которая была вызвана неправильной работой механизма timer_heap в библиотеке timertt.

Эта библиотека написана мной осенью 2014-го года для того, чтобы можно было окончательно отвязать SObjectizer от ACE. И как раз тогда, чуть ли не в самой первой версии, допущена ошибка в операции удаления таймерной заявки в механизме timer_heap. Этот timer_heap реализован в виде binary heap на базе вектора. И как раз удаление из вектора и содержало проблему.

То, что я допустил достаточно дурацкую ошибку совсем не удивительно. Я вообще умудряюсь делать на удивление много ошибок при реализации простых структур данных (скажем, если приходится вручную программировать интрузивный двусвязный список, то я там обязательно в паре мест накосячу). Дополнительным отягчающим фактором стало то, что специфическое для timer_heap тестирование было проведено "по верхам". Думаю, что если бы в 2014-ом не поленился составить тест на базе примитивного fuzzing-а, то эта проблема вскрылась бы уже тогда. Но невнимательность + разгильдяйство сделали свое темное дело.

Более удивительно то, что этот баг проявился в полный рост только сейчас, в 2026-ом. Вот это внушаить 🤔

Какие выводы можно сделать?

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

PS. Что меня еще очень сильно удивило, так это то, что люди смогли найти проблемное место в не самом тривиальном (даже для меня) коде. И, к тому же, предложили патч на базе которого я в итоге и сделал исправление. Значит пишу не такой уж и страшный код, если в нем можно разобраться.

PPS. Видимо, нужно найти время и вытащить timertt из старого svn-репозитория на SourceForge чтобы он продолжил жить на GitHub-е. Плюс выбросить оттуда MxxRu и перевести все на CMake (собственно, необходимость бодаться с CMake и является основным стоп-фактором). Нужно как-то себя заставить сделать это. Жаль только, что история коммитов при переносе в git потеряется 🙁

PPPS. Обновление для SObjectizer-а уже опубликовано в виде версии 5.8.5.1.

воскресенье, 10 мая 2026 г.

[life.audiophilia.diy] Кратко о динамиках, с которыми довелось познакомиться и некоторые общие впечатления

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

Сперва, очень кратко, перечень с личными впечатлениями. Затем поделюсь своим субъективным взглядом на то, как меняется звук динамиков из магазинчиков на Aliexpress с увеличением их цены.

Итак, вот что вспоминается из недавних приобретений:

15.4mm 32ohm Ceramic Titanium PU Composite Diaphragm (золотистый композит на прозрачной диафрагме).

Крутые динамики. Все хорошо и с НЧ, и с ВЧ, но главное их достоинство -- это СЧ. Плотный, как бы округлый и обволакивающий звук, но при этом с отличной детализацией. Хотя из-за плотности может немного не хватать "воздуха" и "прозрачности". Для меня они, временами, слишком "темные", как раз того самого "воздуха" при долгом прослушивании недостает, поэтому я их периодически слушаю, но затем откладываю в сторону т.н. накапливается некоторое утомление от настолько "плотного", насыщенного низкими частотами, звука.

15.4mm 32ohm Ceramic Alloy Diaphragm (оранжевый композит на черной диафрагме).

Самые шикарные ВЧ и СЧ из того, что побывало у меня в руках. При этом полное отсутствие НЧ.

15.4mm 32ohm Ceramic Titanium Alloy Composite Diaphragm (голубой композит на прозрачной диафрагме).

Очень крутые ВЧ и СЧ. ВЧ особенно впечатляют по детализации и "деликатности", по сравнению с ними ВЧ от любимых мной LCP-динамиков воспринимаются уже как грубые, колкие и примитивные. С НЧ ситуация сложная. Во многих случаях мне баса хватает, но не всегда. Любителям накачки на низах точно не хватит. Объективно, громкость этих динамиков заметно падает на частотах ниже 80Hz, поэтому местами эти динамики ощущаются более "светлыми", чем конкуренты. Любопытный эффект: пару-тройку дней слушаешь с удовольствием и наслаждаешься их техничностью и мельчайшими деталями, а потом ловишь себя на том, что звук оказывается очень скучный. Да, техничный. Да, ровный. Да, с проработкой мельчайших деталей. Но очень скучный. Возможно как раз из-за некоторой нехватки НЧ. Тем не менее, это, пожалуй, самое интересное из последних приобретений. После знакомства с данными динамиками слушать любимые мной LCP-динамики стало сложнее, т.к. ВЧ в LCP гораздо "жестче" и с меньшим количеством "оттенков" и "нюансов". Хотя казалось бы... Ведь ранее по детализации у LCP практически не было конкурентов.

15.4mm 32ohm Cobalt Diaphragm. Отличные динамики с хорошей детализацией, очень приятной тоналкой и глубокими НЧ. Являются прямыми конкурентами самых первых динамиков из этого обзора, но чуть более резкие, контрастные и как раз более "прозрачные", чем динамики с керамическо-титаново-полиуретановым композитом. Мне показалось, что по детализации эти чуть чуть, но уступают всем трем перечисленным выше. Поэтому если хочется выслушивать самые-самые тонкие детальки, то нет. А вот если нужен объемный и тяжелый бас, то эти выигрывают. Поэтому-то я их редко слушаю, в какой-то момент складывается впечатление, что НЧ доминирует, а музыка звучит более гнетуще, чем хотелось бы.

В этот обзор не попала еще пара динамиков, которых, увы, на Aliexpress больше нет. Поэтому ссылки на них не даю, т.к. не вижу в этом смысла, ведь приобрести их нельзя.

Теперь же поделюсь субъективным мнением о тенденции, которую наблюдаю приобретая все более и более дорогие динамики.

У меня складывается ощущение, что чем дороже динамики, тем больше в них ВЧ и тем меньше НЧ.

Это значит, что с большой долей вероятности в динамиках за 5USD будет гораздо больше баса и гораздо меньше деталек на высоких, чем в динамиках за 25USD. Более того, может оказаться, что в дорогих динамиках НЧ как бы и нет. Т.е. что-то где-то далеко на заднем фоне услышать можно, но это нужно выслушивать.

Ярчайшим примером здесь служат упомянутые выше динамики с оранжевым композитом на черной диафрагме, где НЧ как будто нет как класса.

Но, при этом, динамики с недостатком НЧ, как ни странно, производят серьезный ВАУ-эффект. За счет того, что НЧ мало и они отведены далеко назад, происходят две прикольные штуки:

  • лучше слышны мельчайшие детали на ВЧ и больше подробностей на СЧ (добавим сюда еще и то, что в техническом плане дорогие динамики реально более детальные и имеют меньше искажений). Поэтому при переходе с дешевых драйверов на дорогие просто поражаешься тому, насколько же больше ты слышишь нюансов в одной и той же музыке. Как раз то, что НЧ мало, и позволяет сконцентрироваться именно на ВЧ. Т.е. за счет отсутствия информации о НЧ невольно приходится довольствоваться ВЧ;
  • усиливается эффект 3-мерности. Когда НЧ мощные, то ударные и контрабас звучат как будто бы совсем рядом. А когда НЧ мало, то их звук доноситься как бы издалека. И кажется, что вокалист стоит прямо перед тобой, а барабанщик с контрабасистом где-то далеко за ним.

С непривычки эти два фактора поражают настолько, что первые несколько дней оказываешься совершенно очарованным новым звучанием и с большим интересом переслушиваешь всякое разное. При этом часто ловя этот самый ВАУ-эффект, когда старые и заслушанные до дыр композиции начинают звучать по новому. Особенно интересно для меня лично начинает восприниматься легкий инструментальный джаз (если этот жанр применим к таким группам как GoGo Penguin и Tingvall Trio) и тяжелый метал (скажем, альбом Senjutsu от Iron Maiden).

Однако, чуть позже приходит осознание, что в звуке чего-то все-таки не хватает. И когда начинаешь сравнивать с более басовитыми динамиками, то становится понятно чего: у тебя как будто бы ловко крадут часть звуковой информации (а именно НЧ), пытаясь спрятать эту кражу большим количеством ВЧ.

Так что для себя я пришел к выводу, что чем выше стоимость динамиков, тем больше ВЧ там будет. Но вот будет ли там достаточно НЧ -- это открытый вопрос.