суббота, 12 декабря 2009 г.

[comp.prog.flame] Samsung Bada – маразматическая C++ платформа

Не так давно Samsung анонсировал собственную платформу для разработки приложений для мобильных устройств – Bada. Основным языком разработки для нее является C++. Но какой C++? C++ без исключений, без умных указателей, без использования RAII, без STL. И это в XXI-ом веке! Маразм крепчал, однако.

С подачи одного из разработчиков Poco я пролистал презентацию по платформе Bada. Желание смотреть на Bada пропадает после двух первых примеров: использования двухфазной инициализации объектов и кодов возврата+макросов вместо исключений.

Объекты в Bada нужно инициализировать посредством явного вызова метода Construct:

class TwoPhaseClass {
  public:
    TwoPhaseClass(void) : p1(null), p2(null) { }
    ~TwoPhaseClass(void) { delete p1; delete p2; }
    
    result Construct(void) {
      SimpleClass* p1 = new SimpleClass();
      SimpleClass* p2 = new SimpleClass(); // Out-of-memory error.
    }

  private:
    SimpleClass* p1;
    SimpleClass* p2;
};

void MyClass::SomeFunction() {
    // Calls the constructor which does not throw an exception.
  TwoPhaseClass a;
    // Calls the Construct() method which allocates two SimpleClass objects.
    // Destructor is called because ‘a’ itself is fully constructed.
  result r = a.Construct();
  ...
}

Какая религия им запретила использовать для p1 и p2 класс std::auto_ptr – не понятно.

А вот работа без исключений еще прикольнее:

result r = E_SUCCESS;
...
// Case 1: The method returns a result.
r = list.Construct(...);
if (r != E_SUCCESS) // identical to 'if (IsFailed(r))'
{
  // Process the error condition.
}
// Case 2: The method sets the result in the method body or returns null.
pObj= list.GetAt(...);
if (GetLastResult() != E_SUCCESS) // or 'if (pObj== null)'
{
  // Process the error condition.
}
// Case 3
r = pObj2->Construct(..);
TryCatch(r == E_SUCCESS, , "[%s] Service could not be initialized.",
  GetErrorMessage(r));
...
CATCH:
  delete pObj1;
  delete pObj2;
  return;

Здесь следует обратить внимание на TryCatch и CATCH – это как раз то, что предлагается вместо нормальных C++ исключений. А следующий пример демонстрирует всю мощь и силу корейской программистской науки:

result r = E_SUCCESS;
...
// Case 1: Use a `goto CATCH'.
r = pList->Construct(...);
TryCatch(r == E_SUCCESS, delete pList, "[%s] Propagated.", GetErrorMessage(r));
...
CATCH:
  SetLastResult(r);
  return null;

// Case 2: Return a result.
  r = list.Construct(...);
  TryReturn(r == E_SUCCESS, r, "[%s] Propagated.", GetErrorMessage(r);

// Case 3: Return null.
  r = list.Construct(...);
  TryReturn(r == E_SUCCESS, null, "[%s] Propagated.", GetErrorMessage(r);

// Case 4: Convert an error condition into another error condition.
  r = list.indexOf(...);
  TryReturn(r == E_SUCCESS, E_INVALID_ARG, "[E_INVALID_ARG] converted from '%s'.",
    GetErrorMessage(r));

Ну что тут скажешь… Опыт разработчиков первых версий Symbian им явно не указ. Наличие большого количества C++ных библиотек и приложений, написанных на “нормальном” C++ с исключениями, STL и даже с Boost-ом – тем более.

Особо умиляет мотивация отказа от исключений – мол очень высокий run-time overhead. Трындец, просто. Во времена, когда у смартфонов устанавливаются гигагерцные процессоры и гигабайты памяти, накладные расходы на обработку C++ исключений кто-то рассматривает всерьез? Афигеть. Мы, в свое время, на 386-х и 486-х как-то умудрялись и C++ исключения использовать, и умные указатели, и даже STL. И все это на 40MHz процессорах с 4Mb памяти на борту. В общем, чего-то я не понимаю :-/

Желающие могут пролистать презентацию до конца. Там еще много забавного. Например, собственные контейнеры. Но по мне вывод однозначен – в топку такую платформу.

PS. А ведь, по слухам, Samsung собирается провести конкурс среди разработчиков с призовым фондом в несколько миллионов долларов ($2.7M призовой фонд и $300K главный приз). Редиски, блин. Их бы энергию, да в мирных целях.

пятница, 11 декабря 2009 г.

[life.thoughts] Об уровне удовольствия в крови и душевном эксгибиционизме

…заставляет задуматься очередное откровение Криса Касперски, который пишет сейчас на RSDN под псевдонимом мыщъх.

Почитаешь его и складывается впечатление, что несмотря на все профессиональные достижения это очень несчастный человек.

Ну жалеть его пусть жалеют более жалостливые люди, чем я (опять вспоминаются слова “когда я вижу сломанные крылья, нет жалости во мне и не спроста”). Важно другое – временами работа может быть спасением. Это как некий защитный панцирь, в котором можно спрятаться от окружающего мира. Но только временами. Хорошо бы об этом почаще вспоминать, особенно когда в очередной раз на работе проводишь по 12 часов, или просиживаешь там очередные выходные. Воруя, по сути, время у своей семьи.


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

Читая такие откровения еще раз понимаешь, почему мне не суждено стать писателем – то, что для писателя творчество, мной воспринимается как “душевный эксгибиционизм” – получение удовольствия от выплеска собственных эмоций на публику. Причем так, чтобы это был именно оргазм, а не жалкая поллюция ;)

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

четверг, 10 декабря 2009 г.

[comp.prog] Статьи Мэтью Уилсона о качестве ПО в журнале Overload

Статья первая: Quality Matters: Introductions, and Nomenclature
Статья вторая: Quality Matters: Correctness, Robustness and Reliability

Кто такой Мэтью Уилсон? Программист, разработчик таких OpenSource проектов, как STLSoft, Pantheios, FastFormat, recls и др. Автор книг “Imperfect C++: Practical Solutions for Real-Life Programming” (вот ее русский перевод) и “Extended STL, Volume 1: Collections and Iterators” (ее русский перевод). А так же автор статей в различных журналах.

Кому-то очень не нравится, как пишет Страуструп. А у меня таким невоспринимаемым автором является Мэтью Уилсон. Пытался читать его Imperfect C++, как на английском, так и на русском – в районе половины книги сдался. Пишет он, пишет, читаешь его, читаешь… Потом пытаешься осознать, а что же ты прочитал, и оказывается, что вспомнить нечего. С его статьями похожая ситуация.

Библиотек я его так же не использовал никогда. Раньше несколько раз смотрел на STLSoft. Забавная там идея – все только в h-файлах, ничего не нужно компилировать. Этакая большая header-only библиотека. Но вот не понял как же с STLSoft писать кроссплатформенные приложения, поскольку STLSoft представляет из себя сборище из каких-то модулей под названиями WinSTL, UNIXSTL, COMSTL, ACESTL. Как все это упрятать под общий фасад? Вроде как есть там что-то под названием PlatformSTL, которое как раз для этих целей предназначено, но беглый просмотр документации не позволил понять, что же это за зверь и с чем его едят.

А FastFormat хочется посмотреть. Должна быть интересная штука. Может когда-нибудь руки дойдут.

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

Первая описывает имеющий место быть парадокс:

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

(за точность перевода я очень сильно не ручаюсь, поэтому вот оригинал: Software entities are exact and act precisely as they are programmed to do, yet the behaviour of (non-trivial) computer systems cannot be precisely understood, predicted, nor relied upon to refrain from exhibiting deleterious behaviour).

Особенно ярко этот парадокс проявляется при агентно-ориентированном подходе. Логика поведения каждого агента понятна, но вот в совокупности они производят такие эффекты, что временами вообще невозможно понять, что и как работает.

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

Вторая фраза декларирует, что может считаться спецификацией программы:

Спецификация: спецификация программного компонента – это сумма всех пройденных компонентом unit-тестов.

и/или

Спецификация: спецификацией программного компонента является сумма всех его ненарушенных контрактов.

Вот такой вот взгляд на мир. Не то, чтобы я его разделял, но задуматься заставляет.

[life.photo] Непонятные для меня вещи: женская тяжелая атлетика

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

В завершение, возможно фейковский, снимок для иллюстрации несовместимости женщины и железа:

 

Кстати, если это реальный снимок, то было бы интересно узнать, кто это такая.

среда, 9 декабря 2009 г.

[comp.prog.idea] Обновление exe-шника для дочернего процесса

Работаю сейчас над проектом, в котором процесс-менеджер запускает N одинаковых дочерних процессов и распределяет работу между ними. В случае проблем с дочерними процессами (аварийное завершение, например) процесс-менеджер запускает вместо сбойного процесса новый дочерний процесс. При работе под Windows в этой схеме есть неприятная особенность: нельзя изменить exe-файл запущенного процесса. При разработке это проявляется особенно часто – изменяешь что-нибудь в исходнике, запускаешь компиляцию и получаешь в лоб сообщение от линкера о том, что exe-файл не может быть заменен, поскольку процесс-менеджер остался запущенным :) Да и в процессе эксплуатации может потребоваться быстренько заменить exe-шник дочернего процесса новой версией.

Идея проста. В конфигурации процессу-менеджеру указывается имя exe-файла дочернего процесса. Например:

{child_process
  {executable "./trx_processor.exe"}
  {args "..."}
}

Но процесс-менеджер не запускает указанный exe-шник напрямую. Вместо этого он генерирует уникальный идентификатор и формирует на его основе новое уникальное имя exe-файла. Так, вместо trx_processor.exe получается имя, скажем, ./tmp/trx_processor-20091207-190200-102-38452.exe. Исходный exe-файл копируется под новым уникальным именем. И запускается уже новый exe-файл.

Процесс-менеджер запоминает размер и дату/время обновления исходного exe-файла (можно и контрольную сумму подсчитывать). Периодически, по таймеру или при получении новых транзакций, процесс-менеджер проверяет исходный exe-файл. Если его размер или дата/время (или контрольная сумма) изменилась, то процесс-менеджер понимает, что дочерний процесс обновился. Поэтому старые процессы дочерние процессы нужно завершать, а вместо них стартовать новые процессы. При старте новых процессов так же генерируется уникальное новое имя, происходит копирование, сохранение размера и даты/времени исходного exe-файла и т.д.

Так же процесс-менеджер должен периодически удалять уже не нужные exe-файлы с уникальными именами. Хотя этим может заниматься и какой-то внешний скрипт.

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

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

Примечание. В таком виде данная схема будет работать только, если в exe-шник дочернего процесса статически влинкованны все нужные библиотеки. Если же вместе с exe-файлом поставляется набор dll-ек, то ситуация усложняется. В таком случае я бы делал подкаталог с уникальным именем, куда копировал бы exe- и dll-файлы, и оттуда бы уже запускал exe-шник дочернего процесса.

вторник, 8 декабря 2009 г.

[life.photo] Ski Dubai – искусственный снег как аттракцион

Мне лично в нашем климате тепла не хватает, иной раз даже летом. А в Дубае сделали аттракцион с искусственным снегом:

Бывает же. А может арабы правы? В последние годы такие мягкие зимы, что подобные аттракционы можно и у нас строить.

Кстати говоря, вот сайт этого чуда: http://www.skidxb.com (там есть раздел “Галерея”, в котором представлены фотографии с начала строительства).

[comp.prog] Где же используются системы анализа и верификации программ?

Попробовал поискать информацию о том, где использовались, используются или будут использоваться средства для анализа и верификации программ (по следам заметки у меня в блоге и в блоге “Алёна C++”).

Анализатор C-шных программ под названием ASTREE использовался для верификации частей бортового ПО Airbus A340 (2003-й год), ПО Airbus A380 (2004-й год) и ПО для управления стыковой космического аппарата Jules Vernes Automated Transfer Vehicle. (Все это написано на стартовой странице проекта).

Язык SPARK (специальное подмножество языка Ada о котором я когда-то уже упоминал) выбрали для реализации части ПО нового боевого вертолета в Англии. Ранее SPARK Ada был выбран в качестве инструмента для разработки ПО для планирования и управления полетами самолетов (eao197: если я не ошибся в переводе). Так же в 2007-м году Paraxis (разработчик SPARK-а) был назначен исполнителем £10-миллионного контракта на разработку новой системы контроля за авиатрафиком в Англии. В 2006-м году Paraxis выиграл контракт на разработку ПО для Engine Monitoring Unit для двигателя Rolls-Royce Trent 1000 (который планировалось использовать в Boeing 787). (Эта информация была найдена в разделе News компании Paraxis High Integrity Systems. Там же упоминалось, что они имеют опыт разработки ПО для нескольких поколений боевых самолетов-истребителей.)

Продукт Parasoft C++test использовался для тестирования ПО систем контроля и управления (компания Intermoco из Австрации), для тестирования ПО систем кондиционирования воздуха (компания Trane). для тестирования ПО для хирургического оборудования (компания Bovie Medical Corporation), для тестирования ПО в области телекоммуникаций и мобильной связи (компания NEC Telecom Software Philippines). (Эта информация была найдена в разделе С++test Case Studies. Все материалы очень поверхностные, обычный коммерческий bullshit, но последняя более-менее интересная.)

Продукт PolySpace использовался для проверки ПО сигнальной системы высокоскоростных поездов во Франции (язык Ada); для проверки ПО, управляющего впрыском топлива в дизельных двигателях (языки C/C++); для проверки ПО, управляющего срабатыванием автомобильных подушек безопасности (C/C++); для проверки ПО, обслуживающего ядерные реакторы (eao197: вот и ядрёные реакторы, как же без них ;)) – как я понял, там проверяется компонент, отвечающий за измерение потока нейтронов. (Эта информация была найдена поиском по сайту MathWorks.)

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

[comp.prog.c++] std::istream, Poco::Base64Decode и std::ios::failbit

Никогда не был любителем C++ных потоков ввода-вывода (это которые std::istream, std::ostream и иже с ними). Дизайн у них какой-то… выхереный, как говорили в нашем дворе когда-то. Пытался по молодости разобраться, как писать свои stream-ы, плюнул, старался их меньше использовать. Собственно, я понимаю, что не люблю кошек потому, что не умею их готовить. Но все-таки. Вот на днях в очередной раз наткнулся на вещь с потоками, которую сложно понять умом. Как хорошо было сказало в старом анекдоте: “Запомните это дети, поскольку понять это невозможно”.

Итак, суть в том, что нужно преобразовать текст из Base64 в нормальный вид. С использованием класса Poco::Base64Decoder это идиоматически выглядит так:

std::string base64decode( const std::string & what )
  {
    std::istringstream instream( what );
    Poco::Base64Decoder decoder( instream );

    std::string result;
    Poco::StreamCopier::copyToString( decoder, result );

    return result;
  }

Но у этого кода есть существенный недостаток – не порождается исключений, если в what находится не Base64 строка. Чтобы исключения порождались, нужно воспользоваться методом std::basic_ios::exceptions:

Poco::Base64Decoder decoder( instream );
decoder.exceptions( std::ios::badbit | std::ios::failbit );

Теперь, казалось бы, все должно быть нормально – если на вход подается не Base64, то порождается исключение (срабатывает битовый флаг badbit).

Но есть засада! Если на вход подать пустую строку, то исключение так же выскочит. Но уже благодаря битовому флагу failbit (по крайней мере это так в Visual C++ 2003/2008 и в MinGW 3.4.5).

Самое внятное описание роли флагов badbit и failbit мне удалось найти в руководстве по стандартной библиотеке C++ от Apache. Там приводится пример двух ситуаций, когда при достижении конца потока в одном случае выставляется failbit, а в другом случае – нет. И, вероятно, один из подобных случаев я поимел, когда подсунул Base64Decoder пустую строку (аналогичная ситуация возникает и без Base64Decoder, когда из пустого потока пытаешься прочитать строку).

Там же в Apache-вском руководстве дан интересный совет: устанавливать с помощью exceptions() только badbit, но не устанавливать eofbit и failbit. Мол, ситуации, которые провоцируют установку eofbit и failbit, обычно не являются исключительными.

Однако, моя параноидальная натура сопротивляется такому совету. Ведь если failbit может быть установлен независимо от eofbit, то хотелось бы эту ситуацию обработать. Ошибка же, как никак. Посему, корректным решением мне видится такое использование Base64Decoder:

std::string base64decode( const std::string & what )
  {
    std::istringstream instream( what );
    Poco::Base64Decoder decoder( instream );
    decoder.exceptions( std::ios::badbit );

    std::string result;
    Poco::StreamCopier::copyToString( decoder, result );
    if( !decoder.eof() && decoder.fail() )
      throw Poco::RuntimeException( "Some error reading Base64 stream" );

    return result;
  }

Что, с моей точки зрения, не есть красиво :(

Мораль сей басни: разработчики Poco – редиски. Нет чтобы сделать выбрасывание исключений в Base64Decoder при обнаружении не-Base64 символа вне зависимости от std::stream-овских флагов исключений! (Шутка).

воскресенье, 6 декабря 2009 г.

[life.flame] Объяснение проблемы Сергею Зефирову

Данная заметка является следствием вот этого комментария в ЖЖ Сергея Зефирова (известного как thesz):

Это факт. Но в чём суть проблемы, ты не сказал ни слова.

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

До этого я в двух комментариях давал объяснение проблемы. Но, поскольку эти объяснения оказались неудовлетворительными, попробую еще раз. Для чего приведу как оригинальный текст заметки Сергея Зефирова, так и последовавшие за этим комментарии (те, что имеют отношение к нашему разговору).

Заметка “Наткнулся у 17ur на отличное”:

...сволочь вынуждают к карьере, потому что ей больше идти некуда.

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

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

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

Это, что, комплекс такой?

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

Ужас просто.

Такое ощущение, что с зомбированными разговаривал.

Тезис 17ur - перефраз принципа Питера насчёт уровня некомпетентности в карьерном росте. Даже не перефраз, а просто одна из иллюстраций этого принципа, насколько я помню. Меня это зацепило именно упоминанием характеристики личности, это раз, и тем, что определённые личности не свободны в своём выборе, это двас.

Просто я впервые сталкиваюсь с несвободными в жизненном выборе людьми.

Наверняка я сталкивался и раньше, но теперь это на осознанном уровне, поэтому и внове.

После чего комментарии:

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

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

PS. Не москвич и даже не понаехавший.

thesz:
Что за проблема-то?

Где проблема-то?

eao197:
Повторю еще раз: ты ничем не отличаешься от упомянутых тобой карьеристами, но считаешь себя лучше.

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

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

Проблема Сергея Зефирова появляется в том, что он берется судить чужие системы ценностей, а свою собственную явно считает лучшей. Не желая при этом даже допустить мысль о том, что его собственная жизнь может казаться кому-то никчемной и пустой, а его жизненные взгляды оторванными от реальности. Грубо говоря, спихивая “карьеристов” в позорную яму, он не замечает, что сам может оказаться в ней же.


Достаточно. Все “знающие жизнь” и “поучающие жизни” идут лесом. В том числе и я сам.