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

How to force pdb loading in WinDbg

Прислали dmp файл, но оказалось, что pdb имеет размер 0. Это очень плохо, но есть же репозитарий — слил нужную версию версию и пересобрал. Но pdb все равно не подходит, т.к. checksum не совпадает. Неизвестно почему, может быть из-за даты сборки или ещё по какой-то причине. Но я точно знаю, что pdb тот, что нужно. В Visual Studio — это тупик, но не в WinDbg.

Пишем команду .symopt+0x40 и WinDbg, зыбыв про контрольную сумму, загружает pdb. Эта команда включает опцию SYMOPT_LOAD_ANYTHING. Про другие параметры можно посмотреть в MSDN.

среда, 10 декабря 2008 г.

Партнерство с Microsoft

Недавно организовал заключение партнерского соглашения с Microsoft. А именно вступили в программу Empower for ISVs. Оказалось сделать это очень просто. Участие стоит 420$ за первый год + столько же за второй. На первом уровне учавствовать можно два года максимум, потом нужно переходить на следующий. Требуется зарегистрировать в их каталоге продукт, которые вы хотите делать.

Бенефиты следующие — дают Visual Studio 2008 Professional на 5 разработчиков и подписку MSDN Premium, что включает в себя почти все виды операционных систем, которые можно использовать для разработки, т.е. не на компах в бухгалтерии. Для бухгалтерии же дополнительно припасено ещё 5 комплектов Windows Vista (Business Edition) и Office 2007 (Professional Edition) — их можно ставить где угодно в компании. Это ещё не все... дополнительно для организации бизнеса даются также лицензии на Windows Server 2008, Exchange 2007 Server, SQL Server 2005, Office SharePoint Server 2007. Все они Standard or Enterprise Edition на Ваш выбор. Дополнительно дается два звонка в службу поддежки(ещё не разбирался о чем это).

Короче, дается все, чтобы начать небольшой бизнес по разработке софта. Останется взять в аренду офис с компами :). У нас все это уже было(в смысле компов и прочего), а нужно было обновить средство разработки и тут получилась большая экономия средств. На остальные рабочие места покупали софт отдельно и не такой навороченный (например, Studio 2008 Standard достаточно в большинстве случаев, а где-то даже Ubuntu+Eclipse хватает, но это уже отдельная история).

Комплект приходит в виде двух чемоданчиков с кучей дисков в них:





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

четверг, 4 декабря 2008 г.

Начинающим программистам



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

Мы, со своей стороны, готовимся к собеседованию, поэтому совет, который, вероятно, подойдет при собеседовании в любой фирме — готовьтесь по теме работы, почитайте книжки, попробуйте реализовать пару алгоритмов на С++. Если Вам выдается такое счастье как анкета, то часто можно понять из неё что интересует нанимателя и освежить в памяти знания по теме(или даже получить новые).

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

Beginners: «Язык программирования С++». Автор — Страуструп. Он лучше всех написал по этой теме, поэтому начинать лучше с его книги. Тем более, что её, наверное, можно купить почти в любом магазине. В крайнем случае, читать в электронном виде. То, что предлагается на кафедрах, часто написано местными работниками кафедры, для того, чтобы иметь публикации как этап в пути к защите или получению какой-либо должности. Качество таких материалов в среднем оставляет желать лучшего (я не исключаю, что есть отдельные хорошие работы, но я их не встречал). На самом деле, после этого этапа уже можно искать работу.

Intermediate: Далее продолжить можно с книгой «Эффективное использование C++» Майерса. Это позволит понять как лучше использовать на практике возможности С++.

Advanced: К этому моменту большинству уже не нужны советы по выбору источников знаний. Если вдруг кто-то не знает, то труды Саттера и Александреску неплохо бы изучить. Можно также почитать про паттерны проектирования для общего развития.

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

Ещё один момент. Достаточно опытные(наверное) разработчики на C приходят к нам с уверенностью, что знают С++ тоже. К сожалению, это не так. Оказывается, что длительное программирование на C скорее вредно. А код в компании весь пишется на С++ и его нужно понимать и уметь поддерживать(и не испортить!). Кстати, это касается не только С, но и математики. Не во всех ВУЗах учат пользоваться знаниями, которые читаются на лекциях, поэтому «отл.» по мат. анализу или красный диплом не означают достаточный для работы уровень.

В завершение, хочу отметить, что наша компания не отказывает навсегда. Можно подучиться и попробовать снова через 6—12 месяцев.

вторник, 25 ноября 2008 г.

Fluendo — ерунда

Попробовал поставить «Fluendo Complete Playback Pack». Все здорово, кроме того, что он ничем не лучше бесплатной версии кодеков, которые есть в репозитарии. Смысла покупать нет, за исключением случая когда в вашей стране есть проблемы с использованием multiverse и universe репозитариев.

понедельник, 24 ноября 2008 г.

Книжка

Заказываю новое, пятое по счету, издание Windows Internal от Руссиновича и Соломона. Обещают доставить к 6-му февраля, ибо предзаказ. Обещают также, что написано там про интерналсы Vista и Windows Server 2008 и книга переработана с учетом новой информации.

суббота, 8 ноября 2008 г.

Пробуем Ubuntu на вкус

Поставил на днях новую версию — Ubuntu 8.10. Обновлением не стал сознательно пользоваться, т. к. хотел посмотреть как работает «из коробки» все это добро.

Есть в новой версии как положительные так и отрицательные стороны. Более всего неприятно удивил процесс установки — после выбора «Установить Ubuntu» система надолго зависла. По всей видимости проблема с моей видеокартой (GeForce 9600GT), т. к. в текстовом режиме инсталляция пошла сразу. Однако, с версией 8.04 таких зависаний не наблюдалось, поэтому записываем в минусы. Кстати дождался установки я со второй попытки и с дистрибутивом для 64-битных систем, поэтому весь дальнейший текст относится к этой версии.

Далее, конечно хотелось настроить беспроводную сеть и это сработало, но что хотелось в Network Manager, то не случилось. Настройки «Подключать автоматически» и «Системная настройка» оказались не совсем тем, что ожидалось — при загрузке сеть не стартует до логина, а это очень неудобно при удаленной перезагрузке. Кроме того, даже после логина Network Manager пытался законнектиться к какой-то видимой, но чужой сети, а вовсе не к моей, со скрытой точкой доступа, которую я указывал вручную. Пришлось оставить старый 100% работающий способ с ручным wpa_supplicant.conf и прописыванием всего необходимого в interfaces. Тут хуже не стало, но ожидания, о которых я писал, не оправдались. Жаль...


Теперь ложку меда в... ну, в общем, в комплекте идут драйвера NVIDIA версии 173 и 177, о которых я упоминал ранее. Версия 177 ставится на ура и даже работает (поэтому 173 пробовать не стал), но программа настройки nvidia-setting почему-то до сих пор запускается из меню Gnome без прав суперпользователя и не может записать файл конфигурации. Но это ещё не все — nvidia-xconfig пришлось запустить вручную, чтобы заработал режим TwinView (да, у меня ещё и телек по кабелю HDTV подключен). В итоге и это заработало. Вывод: если нет телека, то заработает «из коробки».


Далее следует офигенный плюс — сразу запустился фильм, кодированный в VC1, а именно, FULL HD фильм в контейнере TS с DD5 звуком. Было бы здорово, чтобы ещё и аппаратное ускорение работало, иначе звук все-таки запаздывает. Ну и работать стало в mplayer, а вовсе не в моем любимом Totem (он вроде собрался показывать, но ничего у него не вышло). Также автоматически нашлись и все прочие декодеры для mp3, avc, h264 и прочие — это работало и в прошлой версии. Кстати, в диалоге, где выводятся подходящие пакет есть кнопка «Buy Licensed Plug-ins» и ведет она браузер на сайт Cannonical, где за 10–30£ можно купить что-то похожее на порты виндовых кодеков. Стоит попробовать «Fluendo Complete Playback Pack», т. к. там декларируется поддержка VC1 — может тормозить не будет...


Samba server не работает как и раньше. Ну т.е. все нужно настраивать через конфиг, т.к. иначе с виндовых машин даже посмотреть шары нельзя, не говоря о том, чтобы в них зайти. Без правки конфигов нельзя также сделать автоматические монтирование дополнительных партишенов при загрузке. На эти случаи уже были заготовлены готовые smb.conf и fstab.

Обозреватель файлов порадовал опцией «Компактный вид» — она очень удобна при большом количестве файлов.


В комплекте почему-то идет OpenOffice версии 2.4. До 3.0 обновится не сложно, но можно было бы и сразу комплектовать последней версией.

Поддержка NTFS на высоком уровне за исключением старой проблемы, которую можно увидеть на картинке ниже. Но это уже аспекты совместимости с Windows, к которым, возможно, вернусь позже.


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

пятница, 31 октября 2008 г.

Qt Creator IDE

На сайте Qt Software можно скачать первую версию кроссплатформенной IDE для разработки на С++. Это может стать чем-то интересным, на мой взгляд.

Видео презентация с сайта Qt:

среда, 22 октября 2008 г.

Лицензионный договор

Появилась интересная статья на тему ведения переговоров с издателем и подписывания договора при продаже своего продукта. Взгляд с точки зрения законодательства стран СНГ.

вторник, 14 октября 2008 г.

explicit override

Чисто виртуальные классы часто используются для передачи callback-интерфейсов между DLL и EXE. Типичный интерфейсный класс выглядит так:
struct IServerCallback {
virtual void OnStart() =0;
virtual void OnStop() =0;
virtual void OnInfo( void* ptr, long cookie ) =0;
}


Тогда мы у себя создаем реализацию, например так:
class CApplication: public IServerCallback {
CApplication();
virtual ~CApplication();

// Some additional functions
// ...

// IServer callback implemetaion
virtual void OnStart();
virtual void OnStop();
virtual void OnInfo( void* ptr, long cookie );
}


Так вот пока что все в порядке. Но иногда находятся нехорошие люди, которые делают интерфейс не полностью виртуальным, а делают пустую реализацию для некоторых функций. Выяснение причин, почему так происходит, выходит за рамки этой статьи. Выглядит тогда callback-интерфейс, например, так:
struct IServerCallback {
virtual void OnStart() =0;
virtual void OnStop() =0;
virtual void OnInfo( void* ptr, long cookie ) {};
}


И все бы хорошо, пока мы случайно не ошибемся в определении функции. Можно ошибиться в названии или написать const void* ptr вместо void* ptr — не суть. А главное в том, что получим неожиданное поведение — наша функция не будет вызываться. Чтобы избежать этого, можно использовать так называемое explicit override. Как следует из названия, нужно просто явно указать какому интерфейсу принадлежит та или иная функция. Выглядеть это будет так:
class CApplication: public IServerCallback {
CApplication();
virtual ~CApplication();

// Some additional functions
// ...

// IServer callback implemetaion
virtual void IServerCallback::OnStart();
virtual void IServerCallback::OnStop();
virtual void IServerCallback::OnInfo( void* ptr, long cookie );
}


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

UPD: Это работает только в компиляторе от Microsoft и не является стандартом.
UPD: В Microsoft, как я и предполагал, ввели данный синтаксис в Managed C++ для явной реализации интерфейсов(подробнее). Но, оказалось, что это частично можно применять в обычном С++.

четверг, 9 октября 2008 г.

multi_index + shared_ptr

В различных контейнерах бывает удобно хранить не сами объекты, а указатели на них. Тут multi_index позволяет использовать shared_ptr с объектом почти так же как будто там хранится сам объект, включая индексирование по полям этого объекта. Объявление такого контейнера будет выглядеть примерно так:
// структура с кучей нужных полей
struct callback_t {
long system_id;
long server_id;
long callback_id;
// далее что-то ещё есть возможно
};

// определяем тип контейнера
typedef multi_index_container<
shared_ptr<callback_t>, // <<<<< хранится не объект, а указатель на него!
indexed_by<
ordered_unique<
composite_key< // <<<<< индексы объявляются, как если бы мы работали без обертки
callback_t,
member<callback_t, long, &callback_t::system_id>,
member<callback_t, long, &callback_t::server_id>
>
>
>
> callbacks_t;

А использование ничуть не сложнее, чем обычно:
void main() {
callbacks_t lot_of_callbacks;

callback_t* p = new callback_t; // тут конструктор обычно принимает параметры, но упрощено для примера

lot_of_callbacks.insert( shared_ptr<callback_t>( p ) );
// в lot_of_callbacks хранится не сам объект, а указатель на него

// но поиск работает как обычно
callbacks_t::const_iterator cb_iterator = lot_of_callbacks.find( boost::make_tuple( 1, 1 ) );
}

вторник, 7 октября 2008 г.

Ubuntu 8.10 coming soon

Уже некоторое время назад анонсирована новая версия Ubuntu. В моём блоге есть официальный счетчик дней до выхода.

Из всех нововведений самое важно, на мой взгляд, то, что наконец-то появится возможность управлять полноценно сетью через Network Manager. Ранее сеть не работала до логина, если её настраивать через этот самый Network Manager, поэтому приходилось точить конфиги. Теперь обещают, что будет работать...

Более подробно о новых фичах тут. Для любителей KDE тоже есть ссылка - тут можно посмотреть о новинках в Kubuntu.

четверг, 25 сентября 2008 г.

Как раскрыть multi_index iterator

При отладке бывает полезно посмотреть на объект, который скрывается за итератором контейнера multi_index библиотеки boost. В ответе ниже предполагается тип объекта CSource, а экземпляр итератора называется src_iterator:
(CSource*)((((*(boost::multi_index::detail::pod_value_holder<CSource>*)
(&(*(boost::multi_index::detail::index_node_base<CSource,std::allocator<CSource> >*)
(&(*(boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<CSource,std::allocator<CSource> > >*)
(&*((src_iterator).node)))))))).space).data_).buf
Эту строку можно вставлять, например, в окно Watch отладчика Visual Studio.

UPD: Одной строкой (для копирования):
(CSource*)((((*(boost::multi_index::detail::pod_value_holder<CSource>*)(&(*(boost::multi_index::detail::index_node_base<CSource,std::allocator<CSource> >*)(&(*(boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::index_node_base<CSource,std::allocator<CSource> > >*)(&*((src_iterator).node)))))))).space).data_).buf

среда, 17 сентября 2008 г.

MS SQL type XML

С версии SQL Server 2005 тип данных XML стал поддерживаться как отдельный тип и нет необходимости хранить в БД данные этого типа как поле BLOB или nvarchar. Однако, применяя xerces для генерации XML, столкнулся с некоторым ограничением поддержки этого типа. Похоже, что SQL Server не умеет работать с кодировкой UTF-8, поэтому приходится применять UTF-16. В xerces это делается функций setEncoding и при чтении и при записи XML.

вторник, 2 сентября 2008 г.

Debugging symbols in Visual Studio

Думаю, многие знают, что на сайте Microsoft можно скачать отладочную информацию для всех системных компонентов Windows. Они там есть для всех версий Windows и даже для сервис паков. Однако, ОС может быть обновлена в процессе разработки или у клиента. Тогда набор библиотек, вероятнее всего, отличается от фиксированных версий ОС и разбор дампов может быть затруднен. В таком случае, помогает очень удобная функция автоматической загрузки библиотек и отладочной информации к ним непосредственно с сайта Microsoft. Для этого достаточно в студии прописать путь как показано на рисунке ниже.



UPD: на рисунке написано http://msdl.microsoft.com/download/symbols
UPD2: в WinDbg нужно писать SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols

пятница, 29 августа 2008 г.

Mallocator или как написать свой аллокатор

В блоге Visual C++ Team рассказывается как писать собственный аллокатор. Там сказано, что наследование от std::allocator будет не лучшей идеей и приводится пример аллокатора на основе malloc() и free(). В примере достаточно много комментариев и показано, что поменять, чтобы получить аллокатор на свой вкус. Это хорошая отправная точка, если собираетесь написать свой аллокатор.

вторник, 19 августа 2008 г.

disabled warnings in BaseClasses

Сегодня при компиляции конструкции вида
do {
// some code
} while (false);

обнаружилось, что не выдается предупреждении об использовании константы в выражении. Небольшое расследование показало, что виноваты разработчики Microsoft. В одном из файлов BaseClasses обнаружился такой криминал:
// disable some level-4 warnings, use #pragma warning(enable:###) to re-enable
#pragma warning(disable:4100) // warning C4100: unreferenced formal parameter
#pragma warning(disable:4127) // warning C4127: conditional expression is constant
#pragma warning(disable:4189) // warning C4189: local variable is initialized but not referenced
#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
#pragma warning(disable:4511) // warning C4511: copy constructor could not be generated
#pragma warning(disable:4512) // warning C4512: assignment operator could not be generated
#pragma warning(disable:4514) // warning C4514: unreferenced inline function has been removed
#pragma warning(disable:4710) // warning C4710: 'function' not inlined

Вывод тут можно сделать только один - нужно проверять файлы даже от доверенных поставщиков кода и, вообще, быть внимательнее.

Чтобы застраховаться в дальнейшем от таких неожиданностей, нужно сохранить состояние по предупреждениям следующим образом:
#pragma warning( push )
// include external stuff
#pragma warning( pop )

четверг, 14 августа 2008 г.

HD video & Ubuntu

Наконец произошло то, чего я совсем не ждал. NVIDIA выпустила драйвер ветки 173 под Linux, который работает с моим HD телевизором так, как мне того всегда хотелось.

Сначала немного истории... Суть проблемы была в том, что мне подарили телек HD и тут же встал вопрос как его подкючить к компу, чтобы смотреть фильмы. Для начала я тут же поменял свою видеокарту GF6800GT на GF9600GT, т.к. в последней был HDMI выход, что дает всего один кабель, по которому можно передавать звук и видео. Один кабель — это гораздо лучше, чем два. Как купить в России HDMI кабель длинной больше 2 метров — это отдельная история (мне нужен был длиной 7.5 метров). Все было подключено и спрятано в кабельканал плинтуса — просто красота. Но тут же обнаружилась одна проблема — в Ubuntu не заработал звук по S/PDIF (а у NVIDIA именно так он передается на видеокарту). Поиск по форумам дал одну надежду — ждать драйвера ветки 177 и они появились с выходом GeForce 2xx. Все вроде работало неплохо, за одним исключением — звук был очень тихим даже с вывернутым навсю регулятором громкости на компе.

И вот вчера я проверил что новенького на сайте NVIDIA по поводу драйверов. Оказалось, что появились новые рекомендуемые для GF9600GT173.14.12. Я по привычке скачал их и уже хотел поставить, как спомнил про проблему со звуком. Но попробовать все равно решил. И тут случилось то, чего я совсем не ожидал — звук не только работал с этими драйверами, но и был настолько громким, что мог бы разбудить соседей :)

Таким образом, на данный момент проблему звука можно считать оканчательно решенной. Ну разве что, кроме одной мелочи — в проигрователе Totem звук не выводится на телевизор, поэтому приходится пользоваться VLC. Пока не разбирался с этим, но думаю как-нибудь решу и эту проблему — тут хотя бы сорсы есть ;)

суббота, 12 июля 2008 г.

Processing STL containers

Уже не первый раз в ходе code review натыкаюсь на ошибку связанную с организацией обработки того или иного контейнера. Суть проблемы в организации цикла обработки, как показано в примере:
typedef std::list<sometype_t> list_t;
list_t sample_list;
void f( void ) {
// Remove items from list
for ( list_t::iterator it = sample_list.begin(); it != sample_list.end(); ++it ) {
if ( it->condition == true ) {
it = sample_list.erase( it ); // <- errors here !!!
}
}
}


Для начинающих разработчиков, по всей видимости, этот код кажется безобидным. Однако, если внимательно посмотреть, то можно заметить, что после удаления элемента происходит заход на следующий цикл. А что там? Там первым делом происходит ++it, т. е. мы перескакиваем через элемент следующий за удаленным. Плохо? Конечно, но и это ещё не всё. Если мы удалили последний элемент в списке, то it окажется за пределами sample_list.end() и цикл, по всей видимости, завершится уже только из-за ошибки access violation.

Чтобы избежать таких недоразумений лучше написать что-то вроде:
void f( void ) {
// Remove items from list
list_t::iterator it = sample_list.begin();
while ( it != sample_list.end() ) {
if ( it->condition == true ) {
it = sample_list.erase( it );
} else {
++it;
}
}
}


Ещё один интересный момент, это использование такой конструкции для удаления:
sample_list.erase( it++ );

Смотрится симпатичнее варианта со знаком равенства. Однако тут тоже кроется опасность. Если контейнером будет std::list, то ошибки не произойдет. Но что, если мы решили поменять тип контейнера на std::vector, например? А будет вот что: it++ запомнит текущее значение it, которое затем и будет передано в erase – тут все неплохо. Однако перед вызовом erase итератор it будет указывать на следующий элемент контейнера из-за переаллокации элементов контейнера. Для std::vector после работы erase в этом месте будет элемент, следующий за тем, что был нужен. А в худшем случае – опять access violation.

среда, 9 июля 2008 г.

implicit c-tor

Пока пробовал реакцию компиляторов на предыдущий пост обнаружил такую ошибку в gcc (версия 4.2.3 Ubuntu) — следующий код не компилируется, хотя должен:
#include <iostream>

struct type1 {
type1() {};
};

struct type2 {
type2( const type1& ) {};
};

struct sss {
sss( type2 ) {
std::cout << "type2" << std::endl;
};
};

int main() {
type1 x;
sss xxx = x; // <- тут выдается ошибка в gcc
return 0;
}

Поясню что тут должно произойти: класс sss должен конструироваться из класса type2, который, в свою очередь, неявно получается из type1. В компиляторе от Microsoft все так и работает.

Кстати, если писать явно sss xxx( x );,то работает и в gcc.

P.S. Ответ разработчиков gcc был следующим: Only a single user-defined conversion is allowed in an implicit conversion sequence, but the copy-initialization would require two.
Что в переводе означает только то, что та форма инициализации, которая вызывает ошибку, требует два неявных преобразования, а это запрещено.

Остается неясным почему это запрещено(пока не нашел в стандарте) и, если это так и есть, то почему компилятор от Microsoft не выдает ошибку?..

среда, 2 июля 2008 г.

Coding style

Наткнулся при поиске в интернете на стиль написания кода принятый для открытых(а может и закрытых) проектов Google. Требования довольно разумные и могут быть взяты за основу в любой компании, если там пока анархия в этом плане. Смотреть тут.

Дебри boost::multi_index

На днях пришлось выводить тип части композитного ключа в boost::multi_index. Результат меня поразил своим размером... Смотрите сами, для кода ниже:


struct eventinfo_t {
long eventId; /** index **/
long groupId; /** index **/

bool isMarked; /** index **/
bool isHovered; /** index **/
};

typedef multi_index_container<
eventinfo_t,
indexed_by<
/* 0 */ ordered_unique< member<eventinfo_t, long, &eventinfo_t::eventId>>,
/* 1 */ ordered_non_unique< member<eventinfo_t, long, &eventinfo_t::groupId>>,
/* 2 */ ordered_unique<
composite_key<
eventinfo_t,
member<eventinfo_t, bool, &eventinfo_t::isMarked>,
member<eventinfo_t, long, &eventinfo_t::eventId>
>
>
>
> eventmap_t;


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

eventmap_t::nth_index<2>::type::key_type::composite_key_type::key_extractor_tuple::tail_type::head_type::result_type


Если бы частей в композитном ключе было больше, то нужно было бы писать:


...key_extractor_tuple::tail_type::[tail_type:: x <нужная часть>]head_type::result_type


Может есть другой способ?..

четверг, 26 июня 2008 г.

Поиск кода

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


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

понедельник, 23 июня 2008 г.

Будьте гибче

Такой заголовок у новости в журнале "Карьера", которая подтверждает мою недавнюю мысль о графике работы. Там указано, что по исследованиям Wake Forest University среди 3 тыс. человек, выяснилось, что работники с гибким графиком труда или свободным режимом меньше болеют, реже берут больничные и справляются со своими должностными обязанностями более качественно и эффективно, чем те, кто работает по строгому графику.

воскресенье, 22 июня 2008 г.

Статья

Обновил свою статью на codeproject.com посвященную реализации загрузочного окна с информацией о статусе загрузки (либо для индикации каких-то процессов) - так называемого splash screen.

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

четверг, 19 июня 2008 г.

Анкета для собеседования по C++

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

Анкета для собеседования

Недавно я упоминал об анкете при приеме на работу. Анкета у нас содержит вопросы по С++, алгоритмам и техническим моментам работы в Windows.

Ранее мы практиковали тестовые задания, но оказалось, что некоторые кандидаты отказываются от собеседования по этому поводу. Причины тут теперь понятны - имея другое место работы кандидаты не всегда имеют время вникнуть в суть задания и реализовать его. Анкета же позволяет кандидату оценить свою пригодность на конкретную должность, а также требовать оплату адекватно своему опыту и знаниям. Анкета занимает одну сторону листа А4 - это правило. От кандидата требуется оценить свои знания по 4-х бальной шкале:
  • не разбираюсь в этом вопросе
  • читал об этом, знаю определение, принцип работы, не использовал на практике
  • использовал на практике (для С++), пользовался чужой реализацией (для алгоритмов),знаю определения, свойства, могу привести примеры (для математических понятий)
  • могу проконсультировать по этому вопросу (для C++); могу реализовать эффективный алгоритм самостоятельно (для алгоритмов), знаю определения, свойства, могу доказать основные теоремы (для математических понятий).

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

По некоторым направлениям помимо анкеты мы предлагаем ознакомиться с коротким типичным ТЗ (на 3 страницы формата А4). Это нужно, чтобы кандидат сам оценил свои силы и свое же желание работать на указанном направлении.

Пока не понял как выложить тут pdf, как разберусь - покажу пример...

UPD: Посмотреть анкету можно тут.

Чтение

Начал читать книжку iCon про компанию Apple в целом и Стива Джобса в часности. Книга оказалась довольно занимательной и местами захватывающей.

Читаю в русском переводе и немного режет слух, что Кремниевую долину (Silicon valley) называют силиконовой.

вторник, 17 июня 2008 г.

Ошибка в MSVC++

Снова наткнулся на ошибку компилятора. Не очень интересная. Подробности тут.

четверг, 5 июня 2008 г.

Очередная ошибка компилятора

Наткнулся вчера на ещё одну ошибку в компиляторе Microsoft C++. При чем проявляется как в 2005 SP1, так и в 2008 версии. Отправил разработчикам — посмотрим что ответят.


struct XXX
{
int x;
} ();


int main()
{
return 0;
}


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

среда, 4 июня 2008 г.

О графике работы

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

Моё мнение, что в стандартные рабочие часы ( с 9 до 18 ) нужно присутствовать не менее 5 часов. Возможно есть более правильная формула, но такая работает уже несколько лет достаточно эффективно.

пятница, 30 мая 2008 г.

Немного о приеме сотрудников на работу

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

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

вторник, 13 мая 2008 г.

Интервью Дональда Кнута

В переводе интервью на русский язык Дональд Кнут рассказывает о свободном ПО, многоядерных процессора и прочем...

Полная версия интервью доступна тут.

пятница, 28 марта 2008 г.

Переносимый код

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

среда, 26 марта 2008 г.

fun code

Today I've found funny code somewhere in the big project. It looks like the following:
class T
{
public:
// ... some declarations
bool operator ==( T& t )
{
bool b = false;
if ( t == *this ) b = true;

return b;
}
}

Семинар Эдварда Йордона в Москве

Вчера пришло письмо из OZON'a про семинар Эдварда Йордона, который будет проходить в Москве и Питере (дают, кстати, скидку 10% + 5% за предоплату).

Возможно стоит съездить, но есть опасения, что будет просто пересказ книги...

пятница, 21 марта 2008 г.

avi copy with cut function

I've updated avi cut&copy function. Now it can be used standalone completly. Function main implemented just for test to compile working exe file and do not use all functionality range of CopyAvi function.

среда, 19 марта 2008 г.

X или x в структуре/классе ?

Думали тут с коллегой как автоматически определять какие x,y в структуре (ну т.е. большие или маленькие). Это нужно для написания, например, шаблонной функции определения площади многоугольника - чтобы туда можно было передать точки типа POINT с x,y (в GDI) или Point с X,Y (как в GDI+). На каком-то этапе возник код такого вида:
template<int> struct TT {typedef int type;};
template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; }

struct P1 {int x; };
struct P2 {int X; };

int main()
{
P1 p1 = {1};
P2 p2 = {1};

Check_x(p1); // must return true
Check_x(p2); // must return false

return 0;
}
И он не компилируется в Visual Studio (проверено на 2005SP1). Не принимается sizeof в шаблоне, хотя стандарт это позволяет. Баг был послан в Microsoft. Подробнее про баг тут. Кстати сказать, проверка в GNU C++ показала хороший результат - это работает. Зато не сработает код такого вида:
template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; }
это, видимо, тоже баг, но уже в g++. Вторая конструкция была как раз использована для обхода проблемы в компиляторе от микрософт (там, правда, возникли другие проблемы).
Кстати в MSVC++ компилируется и такой код:
template<class P> bool Check_x(P p, typename TT<!(&P::x)>::type b = 0) { return true; }
Кто нибудь знает что он означает? По идее должна выдаваться ошибка на этапе компиляции...

пятница, 14 марта 2008 г.

Syntax highlight in blog

Eventually I have found a script for C++ syntax highlighting in the Blogger. Thanks to developers. Everyone could find it at here. It's very easy to use. Now all my code snippets are looks pretty good.

The key feature of the above highlihter is that the script permanently hosted at http://softwaremaniacs.org/, so that make it possible is to use the script on blogger.com.

четверг, 13 марта 2008 г.

Cut, copy and union video files without recompression


Here is the function (fast and furious) that can be used to copy, cut and union video files without recompression. It uses the Video for Windows (VFW) technology. You can pass a pointer to a callback function lpfnProgress to get an information about the copying progress. Additionally there is the main function in the code to show how to use it.