<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2589006988873069196</id><updated>2012-01-26T18:11:52.319+04:00</updated><category term='C++'/><category term='Ликбез'/><category term='CMake'/><category term='Институт'/><category term='Linux'/><category term='Office'/><category term='Qt'/><category term='Debug'/><category term='Windows'/><category term='g++'/><category term='MSVS'/><category term='Google'/><category term='Методички'/><title type='text'>Кодовство</title><subtitle type='html'>Моя борьба с компьютерными технологиями</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-4136965991442096885</id><published>2011-06-28T11:30:00.002+04:00</published><updated>2011-06-28T11:39:06.386+04:00</updated><title type='text'>Чтобы не забыть команды WinDBG</title><content type='html'>&lt;p&gt;нужно записать их все сюда.&lt;/p&gt;&lt;p&gt;Примерно в таком порядке я их и использую при отладке минидампов из OCA:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;table border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;!sym noisy&lt;/td&gt;&lt;td&gt;Включает подробный лог поиска и загрузки символов&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.reload /f MyApplication.exe&lt;/td&gt;&lt;td&gt;Перезагружает символы для MyApplication.exe. Предыдущая команда позволяет посмотреть откуда и почему не грузит.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;.symopt+0x40&lt;/td&gt;&lt;td&gt;Разрешить грузить даже unmatched PDB файлы&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;kb&lt;/td&gt;&lt;td&gt;Показать наконец стек&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-4136965991442096885?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/4136965991442096885/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2011/06/windbg.html#comment-form' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/4136965991442096885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/4136965991442096885'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2011/06/windbg.html' title='Чтобы не забыть команды WinDBG'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-5206681775424415152</id><published>2010-05-27T11:07:00.002+04:00</published><updated>2010-05-27T11:15:11.343+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Сжатие старых файлов</title><content type='html'>В очистке диска начиная с Windows XP появилась бесполезная возможность сжимать "старые" файлы. Из-за того что система оценивает сколько на этом можно выйграть места приходится долго ждать пока появится возможность удалить всё остальное. Я всё время забываю путь в реестре, где это отключается. Запишу тут (Windows XP):&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Включается&lt;/h2&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Windows Registry Editor Version 5.00&lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Compress old files]&lt;br /&gt;@="{B50F5260-0C21-11D2-AB56-00A0C9082678}"&lt;br /&gt;"Priority"=dword:0000012c&lt;br /&gt;"StateFlags"=dword:00000000&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;h2&gt;Выключается&lt;/h2&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Windows Registry Editor Version 5.00&lt;br /&gt;&lt;br /&gt;[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches\Compress old files]&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-5206681775424415152?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/5206681775424415152/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2010/05/blog-post.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/5206681775424415152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/5206681775424415152'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2010/05/blog-post.html' title='Сжатие старых файлов'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-1383159689797651967</id><published>2010-02-10T09:47:00.001+03:00</published><updated>2010-02-10T09:47:54.352+03:00</updated><title type='text'>jpeg lossless rotation &amp; crop</title><content type='html'>При просмотре фотографий часто выясняется, что держать фотоаппарат боком - не лучшая идея. Приходится разворачивать снимки. Раньше я всегда поворачивал такие изображения только на время просмотра и не сохранял (или сохранял в PNG, что сильно увеличивало размер файла), так как при повторном сохранении в JPEG картинка ухудшится (а мой фотоаппарат сохраняет фотографии именно в JPEG). От этого я особенно не любил встроенный просмотрщик в Windows XP, который при повороте сразу пересохранял изображение.&lt;br /&gt;Оказывается люди придумали решение этой проблемы: &lt;a href="http://www.jpegclub.org/jpegtran/"&gt;jpegtran&lt;/a&gt;, который обеспечивает lossless rotation и crop.&lt;br /&gt;Оказалось также, что есть куча программ, которые это используют, &lt;a href="http://www.jpegclub.org/losslessapps.html"&gt;вот список&lt;/a&gt;.&lt;br /&gt;При помощи gwenview я и развернул и пересохранил большинство своих фотографий. Правда следует учесть что делал я это в gwenview из kde3, gwenview из kde4 (версии 4.3.1) при повороте меняет изображение, что можно заметить даже по пятнам в вычитании двух изображений в GIMP. Насколько я знаю и нагуглил, ImageMagic тоже не умеет вращать или обрезать JPEG без потерь, так что придётся старый gwenview оставить. Под Windows вероятно самым доступным приложением является Irfanview с плагином.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-1383159689797651967?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/1383159689797651967/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2010/02/jpeg-lossless-rotation-crop.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/1383159689797651967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/1383159689797651967'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2010/02/jpeg-lossless-rotation-crop.html' title='jpeg lossless rotation &amp; crop'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-5381798717740712020</id><published>2010-02-01T20:53:00.003+03:00</published><updated>2010-02-01T21:07:06.889+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Linux'/><title type='text'>Планшет G-Pen 560 и openSUSE 11.2</title><content type='html'>Случилось мне прикручивать планшет G-Pen 560 под openSUSE 11.2. Сам планшет без драйверов отлично работает и в Windows и в GNU/Linux как мышка, или как тычпад. Однако ценность планшета именно в абсолютном позиционировании и разной степени давления.&lt;br /&gt;Сначала я попытался делать аналогично &lt;a href="http://klek.blogspot.com/2008/03/genius-g-pen-560-kubuntu-710.html"&gt; инструкции&lt;/a&gt;, однако с поправками на дистрибутив.  WizardPen есть в OBS и доступен &lt;a href="http://software.opensuse.org/search?baseproject=openSUSE%3A11.2&amp;p=1&amp;q=wizardpen"&gt;тут&lt;/a&gt;, поэтому никакой возни со сборкой и установкой.  После загрузки и установки &lt;b&gt;x11-input-wizardpen-0.7.0.alpha2-2.1.x86_64.rpm&lt;/b&gt; и &lt;b&gt;x11-input-wizardpen-tools-0.7.0.alpha2-2.1.x86_64.rpm&lt;/b&gt; запустил калибровку:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;wizardpen-calibrate /dev/input/wizardpen&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;При этом калибровка попросит ткнуть сначала в один угол планшета, потом в противоположный ему и выдаст подобные строки для xorg.conf:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Driver  "wizardpen"&lt;br /&gt;Option  "Device"   "/dev/input/wizardpen"&lt;br /&gt;Option  "TopX" "329"&lt;br /&gt;Option  "TopY" "500"&lt;br /&gt;Option  "BottomX" "11836"&lt;br /&gt;Option  "BottomY" "8910"&lt;br /&gt;Option  "MaxX" "11836"&lt;br /&gt;Option  "MaxY" "8910"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Далее выяснилось что в openSUSE 11.2 файла xorg.conf уже нет, и всё работает автоматически и без него. Тем не менее, я создал xorg.conf при помощи Sax2 и вставил в него эти строки. После перезапуска исков, они стали падать при любой активности планшета.&lt;br /&gt;Добрые люди подсказали что теперь всем заведует HAL, поэтому мучить нужно его. Я удалил ненужный более xorg.conf (если работает без него, значит пусть и работает дальше).&lt;br /&gt;После этого открыл &lt;b&gt;/etc/hal/fdi/policy/99-x11-wizardpen.fdi&lt;/b&gt;, переименовал ключ &lt;b&gt;info.product&lt;/b&gt; из "TABLET DEVICE" в "Aiptek" (надо будет разобраться на досуге зачем) и изменил значения остальных ключей в соответствии с тем, что выдала калибровка. Получился такой файл:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="ISO-8859-1" ?&amp;gt; &lt;br /&gt;&amp;lt;deviceinfo version="0.2"&amp;gt; &lt;br /&gt;&amp;lt;device&amp;gt; &lt;br /&gt;    &amp;lt;!-- "info.product" MUST match the name of your tablet: --&amp;gt; &lt;br /&gt;    &amp;lt;!-- grep -i name /proc/bus/input/devices               --&amp;gt; &lt;br /&gt;    &amp;lt;match key="info.product" contains="Aiptek"&amp;gt; &lt;br /&gt;    &amp;lt;merge key="input.x11_driver" type="string"&amp;gt;wizardpen&amp;lt;/merge&amp;gt; &lt;br /&gt;    &amp;lt;merge key="input.x11_options.SendCoreEvents" type="string"&amp;gt;true&amp;lt;/merge&amp;gt; &lt;br /&gt;&lt;br /&gt;    &amp;lt;!-- Modify these configurations accordingly --&amp;gt; &lt;br /&gt;    &amp;lt;!-- Use "man wizardpen" for the full-set of --&amp;gt; &lt;br /&gt;    &amp;lt;!-- configurable options                    --&amp;gt; &lt;br /&gt;    &amp;lt;merge key="input.x11_options.TopX" type="string"&amp;gt;329&amp;lt;/merge&amp;gt; &lt;br /&gt;    &amp;lt;merge key="input.x11_options.TopY" type="string"&amp;gt;500&amp;lt;/merge&amp;gt; &lt;br /&gt;    &amp;lt;merge key="input.x11_options.BottomX" type="string"&amp;gt;11836&amp;lt;/merge&amp;gt; &lt;br /&gt;    &amp;lt;merge key="input.x11_options.BottomY" type="string"&amp;gt;8910&amp;lt;/merge&amp;gt; &lt;br /&gt;    &amp;lt;merge key="input.x11_options.TopZ" type="string"&amp;gt;75&amp;lt;/merge&amp;gt; &lt;br /&gt;    &amp;lt;merge key="input.x11_options.debugyn" type="string"&amp;gt;0&amp;lt;/merge&amp;gt; &lt;br /&gt;    &amp;lt;/match&amp;gt; &lt;br /&gt;&amp;lt;/device&amp;gt; &lt;br /&gt;&amp;lt;/deviceinfo&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;В TopZ регулируется чувствительность к касанию, настраивается индивидуально.&lt;br /&gt;Воткнул планшет и он заработал как надо! Правда GIMP думает что это Aiptek, но это не суть важно.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-5381798717740712020?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/5381798717740712020/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2010/02/g-pen-560-opensuse-112.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/5381798717740712020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/5381798717740712020'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2010/02/g-pen-560-opensuse-112.html' title='Планшет G-Pen 560 и openSUSE 11.2'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-1094677162045518732</id><published>2010-01-22T19:42:00.009+03:00</published><updated>2010-01-25T15:58:40.544+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ликбез'/><title type='text'>Крабозябры в IRC</title><content type='html'>Меня уже несколько раз спрашивали, и уже надоело объяснять каждый раз заново. Поэтому ответ будет лежать тут, пока не понадобится мне в очередной раз.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Дано&lt;/b&gt;: люди, пишущие гигантской длины сообщения в IRC с кириллицей.&lt;br /&gt;&lt;b&gt;Проблема&lt;/b&gt;: люди видят крабозябры вместо обрезанного сообщения.&lt;br /&gt;&lt;br /&gt;Как написано в &lt;a href="http://tools.ietf.org/html/rfc1459#section-2.3"&gt;RFC 1459 на 8й странице&lt;/a&gt;,&lt;br /&gt;а также в &lt;a href="http://tools.ietf.org/html/rfc2812#section-2.3"&gt;RFC 2812&lt;/a&gt; и&lt;br /&gt;&lt;a href="http://tools.ietf.org/html/rfc2813#section-2.3"&gt;RFC 2813&lt;/a&gt;&lt;br /&gt;на 6й странице:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;IRC messages are always lines of characters terminated with a CR-LF&lt;br /&gt;(Carriage Return - Line Feed) pair, and these messages SHALL NOT&lt;br /&gt;exceed 512 characters in length, counting all characters including&lt;br /&gt;the trailing CR-LF. Thus, there are 510 characters maximum allowed&lt;br /&gt;for the command and its parameters. There is no provision for&lt;br /&gt;continuation of message lines.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Это ограничение довольно быстро достигается в случае длинных сообщений, кроме того перед непосредственно сообщением идёт также служебная информация протокола, которая тоже занимает место в этих 510 байтах. Например, в случае отправки сообщения в канал это выглядит как:&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;PRIVMSG #имяканала :имя сообщения\r\n&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;по двоеточию сервер догадывается, с какого места идёт собственно сообщение. Все лишние байты сервер попросту обрежет. Более того, при передаче другому клиенту сообщение ещё более сократится, чтобы вместить служебную информацию (кто сказал) и все равно уместиться в 510 байт.&lt;br /&gt;&lt;pre style="font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; border: 1px dashed rgb(153, 153, 153); line-height: 14px; padding: 5px; overflow: auto; width: 100%;"&gt;&lt;code&gt;логин!идент@маска PRIVMSG #имяканала :имя сообщения\r\n&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Бороться с нехваткой байт под длинное сообщение можно по-разному. Большинство клиентов либо обрезает сообщение перед отправкой до 512 байт, либо отправляет как есть и тогда его обрезает уже сервер. Некоторые (например, XChat и некоторые скрипты к mIRC) разбивают сообщение на несколько и отправляют их подряд.&lt;br /&gt;&lt;br /&gt;Ситуация усугубляется тем, что в UTF-8 кодировке символы кириллицы представляются двумя байтами. Если разрезать сообщение посреди символа, то такая последовательность байт уже не будет правильной unicode-последовательностью и у многих клиентов возникают проблемы с корректным отображением такой строки. И если WeNet и Rusnet используют однобайтовые кодировки, то на Freenode используется именно UTF-8 и пользователи нередко начинают выяснять отношения.&lt;br /&gt;&lt;br /&gt;Для иллюстрации вышесказанного я нашел свой старый эксперимент по написанию IRC-бота, перенастроил его на FreeNode и дописал следующий код на команду "sayit":&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if(order == "sayit")&lt;br /&gt;{&lt;br /&gt;   // в этой строке 540 байт (UTF-8)&lt;br /&gt;   const char bigline[] = "КрабозябраПридиКрабозябраПридиКрабозябраПриди"&lt;br /&gt;"КрабозябраПридиКрабозябраПридиКрабозябраПридиКрабозябраПридиКрабозябраПриди"&lt;br /&gt;"КрабозябраПридиКрабозябраПридиКрабозябраПридиКрабозябраПридиКрабозябраПриди"&lt;br /&gt;"КрабозябраПридиКрабозябраПридиКрабозябраПридиКрабозябраПридиКрабозябраПриди";&lt;br /&gt;   send_private_message(bigline, channel);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;540 байт это явно больше 510. Моя реализация send_private_message не обрезает сообщения и посылает его как есть. Таким образом, в данном случае обрезание выполняется сервером, который рассылает это сообщение клиентам.&lt;br /&gt;&lt;br /&gt;Для демонстрации я взял IRC-клиенты, находящиеся у меня под рукой: &lt;a href="http://www.kvirc.ru/"&gt;KVIrc&lt;/a&gt; (версии 3.4.3 и 4 из svn), XChat (версия 2.8.6), Konversation (версия 1.2). Интересно было бы проверить ещё на mIRC, но у меня его нет.&lt;br /&gt;&lt;br /&gt;Заведя бота и клиентов на уединённый канал, я несколько раз дал боту комманду "sayit", затем попытался отправить очень длинные строки из каждого клиента и проанализировал результаты.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;KVIrc&lt;/h2&gt;&lt;br /&gt;Этот используемый мной клиент - лучший выбор когда нужно читать. В нём корректно отобразились все строки, посланные всеми клиентами (с учётом укорачивания, конечно). К сожалению, отправляемые строки сам клиент режет по 512 байт, ничуть не заботясь о границах символов. Надеюсь, это кто-нибудь исправит, или хотя бы напишет скрипт.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_joUw660-o64/S1nYEiSWTTI/AAAAAAAAADk/5cfsbkvBdnE/s1600-h/kvirc.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 355px; height: 342px;" src="http://4.bp.blogspot.com/_joUw660-o64/S1nYEiSWTTI/AAAAAAAAADk/5cfsbkvBdnE/s400/kvirc.png" alt="" id="BLOGGER_PHOTO_ID_5429608398206684466" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h2&gt;XChat&lt;/h2&gt;&lt;br /&gt;Этот клиент успешно делить длинные сообщения на несколько, что делает выбором тех, кто пишет. Сообщения от бота он тем не менее пережил нормально, видимо обрезалось удачным для алгоритма образом. А вот длинные сообщения от KVIrc и konversation он показал крабозябрами.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_joUw660-o64/S1nYeSUUEQI/AAAAAAAAADs/JLFQSgVVFyQ/s1600-h/xchat.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 229px;" src="http://1.bp.blogspot.com/_joUw660-o64/S1nYeSUUEQI/AAAAAAAAADs/JLFQSgVVFyQ/s400/xchat.png" alt="" id="BLOGGER_PHOTO_ID_5429608840596558082" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h2&gt;konversation&lt;/h2&gt;&lt;br /&gt;Этот клиент корректно показал сообщения от kvirc, но показал крабозябры от бота. Сам он умеет делить сообщения на несколько, но это совершенно не спасает от проблемы обрезания сообщения сервером после добавления имени и маски.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_joUw660-o64/S1nYorT5aNI/AAAAAAAAAD0/4E5tCG1tmDU/s1600-h/konversation.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 265px;" src="http://3.bp.blogspot.com/_joUw660-o64/S1nYorT5aNI/AAAAAAAAAD0/4E5tCG1tmDU/s400/konversation.png" alt="" id="BLOGGER_PHOTO_ID_5429609019104389330" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h2&gt;Вывод&lt;/h2&gt;&lt;br /&gt;Дело с клиентами IRC обстоит как всегда печально. Повтор одного и того же длинного сообщения несколько раз заставляет клиенты то показывает его правильно, то неправильно. Это видимо зависит от того, как трактует их алгоритм преобразования байт в символы. Если вы хотите избежать выяснения у кого клиент хуже, и что вы пишете-таки в UTF-8 - пишите сообщения покороче.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-1094677162045518732?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/1094677162045518732/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2010/01/irc.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/1094677162045518732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/1094677162045518732'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2010/01/irc.html' title='Крабозябры в IRC'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_joUw660-o64/S1nYEiSWTTI/AAAAAAAAADk/5cfsbkvBdnE/s72-c/kvirc.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-8244592889332866665</id><published>2010-01-20T11:38:00.005+03:00</published><updated>2010-01-20T11:52:29.288+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Qt'/><title type='text'>Qt 4.6.1</title><content type='html'>Тролли ударными темпами делают свою библиотеку. Казалось бы недавно только вышел 4.6.0, как уже готов bug-fix release (&lt;a href="http://qt.nokia.com/developer/changes/changes-4.6.1"&gt;changelog&lt;/a&gt;). В основном эта версия чинит производительность (открытие файла наконец не вызывает stat) и лики. Также починили &lt;a href="http://bugreports.qt.nokia.com/browse/QTBUG-5799"&gt;waitForConnected под Windows&lt;/a&gt;, что радует.&lt;br /&gt;С нетерпением ждём следующих версий.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-8244592889332866665?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/8244592889332866665/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2010/01/qt-461.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/8244592889332866665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/8244592889332866665'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2010/01/qt-461.html' title='Qt 4.6.1'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-5873065654882451654</id><published>2009-11-23T11:02:00.002+03:00</published><updated>2009-11-23T11:04:45.569+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Сообщения об ошибках</title><content type='html'>&lt;code&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;long long long int a;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Компилятор Microsoft:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;error C2632: '__int64' followed by 'long' is illegal&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Скучно и как-то казённо. Вот g++/mingw - другое дело:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;error: ‘long long long’ is too long for GCC&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-5873065654882451654?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/5873065654882451654/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2009/11/blog-post.html#comment-form' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/5873065654882451654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/5873065654882451654'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2009/11/blog-post.html' title='Сообщения об ошибках'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-6557080669011915974</id><published>2009-10-15T12:33:00.007+04:00</published><updated>2009-10-15T13:50:48.704+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Abstraction penalty</title><content type='html'>В порыве философствования на тему «throw – это по сути то же goto» поймал себя на мысли о том, что думаю об исключениях как о дорогостоящей операции. А вдруг это premature optimization? Решил написать быстрый и простой сферический тест в вакууме.&lt;br /&gt;&lt;br /&gt;&lt;table width="100%" bg style="color:#F2F2F2;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt; &lt;span style="color:#000000;"&gt;makeExceptions&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;for&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;i&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#000000;"&gt;i&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;i&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#0000FF;"&gt;try&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span style="color:#0000FF;"&gt;throw&lt;/span&gt; &lt;span style="color:#000000;"&gt;std&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;::&lt;/span&gt;&lt;span style="color:#000000;"&gt;exception&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;();&lt;/span&gt;&lt;br /&gt;           &lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;a&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt;&lt;br /&gt;           &lt;span style="color:#000000;"&gt;a&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;++;&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#0000FF;"&gt;catch&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#000000;"&gt;std&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;::&lt;/span&gt;&lt;span style="color:#000000;"&gt;exception&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;&amp;amp;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;&lt;b&gt;&lt;i&gt;&lt;a href="http://dobrokot.nm.ru/WinnieColorizer.html"&gt;&lt;span style="color:#727272;"&gt;_Winnie C++ Colorizer&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Начав писать такую ерунду, я уже не мог остановиться и решил заодно проверить производительность конструкций &lt;a href="http://www.boost.org/doc/libs/1_40_0/doc/html/foreach.html"&gt;BOOST_FOREACH&lt;/a&gt; и Q_FOREACH, от просмотра реализации которых мне хочется рвать волосы на заднице.&lt;br /&gt;Начал я с простого for:&lt;br /&gt;&lt;table width="100%" bg style="color:#F2F2F2;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt; &lt;span style="color:#000000;"&gt;makeForeachFor&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;const&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;size&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;10&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;a&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;[&lt;/span&gt;&lt;span style="color:#000000;"&gt;size&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;];&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;for&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;i&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#000000;"&gt;i&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;i&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#0000FF;"&gt;for&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;j&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#000000;"&gt;j&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#000000;"&gt;size&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;j&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span style="color:#000000;"&gt;a&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;[&lt;/span&gt;&lt;span style="color:#000000;"&gt;j&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;]&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;&lt;b&gt;&lt;i&gt;&lt;a href="http://dobrokot.nm.ru/WinnieColorizer.html"&gt;&lt;span style="color:#727272;"&gt;_Winnie C++ Colorizer&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;И BOOST_FOREACH:&lt;br /&gt;&lt;table width="100%" bg style="color:#F2F2F2;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt; &lt;span style="color:#000000;"&gt;makeForeachBoost&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;const&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;size&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;10&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;a&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;[&lt;/span&gt;&lt;span style="color:#000000;"&gt;size&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;];&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;for&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;I&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#000000;"&gt;I&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;i&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#000000;"&gt;BOOST_FOREACH&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;x&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;,&lt;/span&gt; &lt;span style="color:#000000;"&gt;a&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span style="color:#000000;"&gt;x&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;&lt;b&gt;&lt;i&gt;&lt;a href="http://dobrokot.nm.ru/WinnieColorizer.html"&gt;&lt;span style="color:#727272;"&gt;_Winnie C++ Colorizer&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Я специально помести его в innermost loop, чтобы сильнее проявили себя накладные расходы на создание и выход из цикла.&lt;br /&gt;Сам массив я выбрал маленьким умышленно, чтобы он влез в любой кэш и не влиял на производительность.&lt;br /&gt;Также есть свой foreach и в Qt. В отличие от BOOST_FOREACH, он не умеет работать с обычными массивами например и копирует контейнер перед использованием. Для Qt-контейнеров это не страшно, так как они все copy-on-write, но для обычных это просто недопустимо. Поэтому я также протестировал эти две реализации foreach на QVector.&lt;br /&gt;&lt;table width="100%" bg style="color:#F2F2F2;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt; &lt;span style="color:#000000;"&gt;makeForeachBoostQt&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;const&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;size&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;10&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#000000;"&gt;QVector&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#000000;"&gt;a&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#000000;"&gt;size&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;);&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;for&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;i&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#000000;"&gt;i&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;i&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#000000;"&gt;BOOST_FOREACH&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;x&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;,&lt;/span&gt; &lt;span style="color:#000000;"&gt;a&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span style="color:#000000;"&gt;x&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000FF;"&gt;void&lt;/span&gt; &lt;span style="color:#000000;"&gt;makeForeachQt&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;const&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;size&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;10&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#000000;"&gt;QVector&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#000000;"&gt;a&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#000000;"&gt;size&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;);&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#0000FF;"&gt;for&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;i&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#000000;"&gt;i&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#000000;"&gt;times&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;++&lt;/span&gt;&lt;span style="color:#000000;"&gt;i&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#000000;"&gt;Q_FOREACH&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; &lt;span style="color:#000000;"&gt;x&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;,&lt;/span&gt; &lt;span style="color:#000000;"&gt;a&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span style="color:#000000;"&gt;x&lt;/span&gt; &lt;span style="color:#C8003C;"&gt;=&lt;/span&gt; &lt;span style="color:#40B440;"&gt;0&lt;/span&gt;&lt;span style="color:#C8003C;"&gt;;&lt;/span&gt;&lt;br /&gt;       &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:#C8003C;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#C8003C;"&gt;}&lt;/span&gt; &lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;&lt;b&gt;&lt;i&gt;&lt;a href="http://dobrokot.nm.ru/WinnieColorizer.html"&gt;&lt;span style="color:#727272;"&gt;_Winnie C++ Colorizer&lt;/span&gt;&lt;/a&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.everfall.com/paste/id.php?y97yq4lk7vjc"&gt;Исходный код файла&lt;/a&gt;&lt;br /&gt;Собирал я его под Windows при помощи MinGW и компилятора от 2005 студии:&lt;br /&gt;gcc version 3.4.5 (mingw-vista special r3)&lt;br /&gt;Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86&lt;br /&gt;и под Linux:&lt;br /&gt;gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Результаты замеров (среднее время в миллисекундах). Использовался 64битный Linux и 32битная Windows XP, процессор - Intel Core2 6420:&lt;br /&gt;&lt;table border="1"&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;br /&gt; &lt;td style="text-align: center;"&gt;&lt;br /&gt;  &lt;b&gt;Cборка&lt;/b&gt;&lt;br /&gt; &lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: center;"&gt;&lt;br /&gt;  &lt;b&gt;Exceptions&lt;/b&gt;&lt;br /&gt; &lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: center;"&gt;&lt;br /&gt;  &lt;b&gt;for&lt;/b&gt;&lt;br /&gt; &lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: center;"&gt;&lt;br /&gt;  &lt;b&gt;Boost&lt;/b&gt;&lt;br /&gt; &lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: center;"&gt;&lt;br /&gt;  &lt;b&gt;Boost(QVector)&lt;/b&gt;&lt;br /&gt; &lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: center;"&gt;&lt;br /&gt;  &lt;b&gt;Q_FOREACH&lt;/b&gt;&lt;br /&gt; &lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt; &lt;td style="text-align: left;"&gt;linux-64-O0&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;3.590&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0350&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.4330&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.4590&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.1360&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt; &lt;td style="text-align: left;"&gt;linux-64-O2&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;3.600&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0400&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.5700&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt; &lt;td style="text-align: left;"&gt;win32-cl&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;2.828&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0312&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.6719&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.6656&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.5844&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt; &lt;td style="text-align: left;"&gt;win32-cl-O2&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;2.812&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0125&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0141&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0734&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt; &lt;td style="text-align: left;"&gt;win32-mingw-O0&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.843&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0532&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.5672&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.6656&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.1937&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;br /&gt; &lt;td style="text-align: left;"&gt;win32-mingw-O2&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.844&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0109&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0125&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0266&lt;/td&gt;&lt;br /&gt; &lt;td style="text-align: right;"&gt;0.0546&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Да, всё как и ожидалось. 3микросекунды на исключение это конечно немало, но если обрабатывать ими действительно ошибочные ситуации, а не строить на них логику программы (файла нет? Исключение! Пользователь нажал "отмена"? Исключение!), то вобщем-то не так уж и много. Хотя goto быстрее, да.&lt;br /&gt;С другой стороны оказалось что оптимизаторы довольно агрессивно оптимизируют реализации foreach. Конечно, их ни в коем случае нельзя использовать в innermost loop, а для более высокого уровня вложенности они действительно упростят код (и усложнять хождение по шагам в отладчике).&lt;br /&gt;Конечно полученные цифры не являются какой либо истиной в какой либо истанции, это всего лишь сферический тест в вакууме. Однако я для себя выводы сделал - и то и то можно без опаски применять, когда пишется например GUI или другой не библиотечный и не критичный ко времени выполнения код (98% кода). Что и требовалось доказать.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-6557080669011915974?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/6557080669011915974/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2009/10/abstraction-penalty.html#comment-form' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/6557080669011915974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/6557080669011915974'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2009/10/abstraction-penalty.html' title='Abstraction penalty'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-6260752567378313308</id><published>2009-09-23T17:50:00.004+04:00</published><updated>2009-09-23T17:59:56.520+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Чистое мыло</title><content type='html'>Видя в интернете изображения мыла с подписью "GMail", думал что это такая шутка.&lt;br /&gt;Оказалось, Google действительно раздаёт такие мыльца на своих конференциях.&lt;br /&gt;Теперь и я обладатель такого:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_joUw660-o64/SropOLw3jRI/AAAAAAAAACQ/fXQqJU_Qq1w/s1600-h/gmail.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 197px;" src="http://4.bp.blogspot.com/_joUw660-o64/SropOLw3jRI/AAAAAAAAACQ/fXQqJU_Qq1w/s400/gmail.png" alt="" id="BLOGGER_PHOTO_ID_5384661628127513874" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-6260752567378313308?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/6260752567378313308/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2009/09/blog-post.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/6260752567378313308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/6260752567378313308'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2009/09/blog-post.html' title='Чистое мыло'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_joUw660-o64/SropOLw3jRI/AAAAAAAAACQ/fXQqJU_Qq1w/s72-c/gmail.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-1768227286403620240</id><published>2009-08-29T22:02:00.007+04:00</published><updated>2009-08-29T22:41:54.415+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CMake'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Тестирование с помощью CxxTest</title><content type='html'>Я вообще не отношу себя к адептам Test Driven Development, но считаю тесты довольно важной и удобной штукой. Правда дальше самопальных тестов к отдельным функциям и классам, выполняемых по #ifdef-у или в отдельном консольном проект дело не шло. Но ведь надо пользоваться чем-нибудь общепринятым, да и вообще уделять тестам больше внимания. Подумав так, решил встроить-таки хотя бы несколько тестов в свой дипломный проект.&lt;br /&gt;В прошлый раз, когда я пытался приучить себя к тестам, меня отпугнула замороченость &lt;a href="http://sourceforge.net/projects/cppunit/"&gt;CppUnit&lt;/a&gt; (клона jUnit для C++), поэтому в этот раз я начал с обзора других средств для тестирования кода на C++.&lt;br /&gt;Вообще я немного поковырял &lt;a href="http://code.google.com/p/googletest/"&gt;googletest&lt;/a&gt;, &lt;a href="http://unittest-cpp.sourceforge.net/"&gt;UnitTest++&lt;/a&gt;, и &lt;a href="http://www.boost.org/doc/libs/1_40_0/libs/test/doc/html/index.html"&gt;даже Boost Test Library&lt;/a&gt;, но речь сейчас не о них.&lt;br /&gt;В конце концов, я искал простое и функциональное решение, безо всяких дурацких регистраций тестов и прочей ненужной синтаксической ерунды.&lt;br /&gt;В конце концов я выбрал &lt;a href="http://cxxtest.tigris.org/"&gt;CxxTest&lt;/a&gt;.&lt;br /&gt;&lt;h1&gt;CxxTest&lt;/h1&gt;&lt;br /&gt;Основные преимущества:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Не требует RTTI и шаблонов.&lt;/li&gt;&lt;li&gt;Не требует механизма исключений для работы (но может их отлавливать при необходимости).&lt;/li&gt;&lt;li&gt;Не зависит и не требует никаких внешних библиотек.&lt;/li&gt;&lt;li&gt;Не требует вручную регистрировать тесты (вот оно!).&lt;/li&gt;&lt;li&gt;Распространяется как набор заголовочных файлов и исходного кода (ну ещё препроцессор отдельно), не требуется сборка никаких библиотек.&lt;/li&gt;&lt;/ul&gt;Итак, как же с ним работать.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Тесты организуются в наборы (suite). Каждый набор представляется классом, наследуемым от CxxTest::TestSuite. Тестами в наборе считаются все функции, имя которых начинается с "test" (в любом регистре, напимер test1, Test_Function).&lt;/li&gt;&lt;li&gt;Если нужно делать инициализацию/деиницилизацию уровня набора, то в нём объявляются статические функции &lt;span style="font-weight: bold;"&gt;createSuite&lt;/span&gt; и &lt;span style="font-weight: bold;"&gt;destroySuite&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Созданный заголовочный файл отдаётся генератору на Perl (cxxtestgen.pl) или Python (cxxtestgen.py), который генерирует исходный файл с точкой входа. В этот файл включается созданный заголовочный файл с тестами&lt;/li&gt;&lt;code&gt;cxxtestgen.py --error-printer -o runner.cpp MyTestSuite.h&lt;/code&gt;&lt;li&gt;Этот исходный файл потом собирается как угодно в приложение, которое и является тестом.&lt;/li&gt;&lt;li&gt;Для тестов есть много разнообразных макросов с говорящими названиями: TS_ASSERT, TS_ASSERT_EQUALS, TS_ASSERT_DELTA или даже TS_ASSERT_THROWS_ANYTHING.&lt;/li&gt;&lt;/ol&gt;Итак, заголовочный файл может выглядеть примерно таким образом:&lt;br /&gt;&lt;pre style="border: 1px solid rgb(208, 208, 208); font-family: monospace; color: black; background-color: rgb(240, 240, 240);"&gt;include &amp;lt;cxxtest h&amp;gt;&lt;br /&gt;&lt;br /&gt;class MyTestSuite : public CxxTest::TestSuite&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt; void testAddition( void )&lt;br /&gt; {&lt;br /&gt;     TS_ASSERT( 1 + 1 &gt; 1 );&lt;br /&gt;     TS_ASSERT_EQUALS( 1 + 1, 2 );&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; void testMultiplication( void )&lt;br /&gt; {&lt;br /&gt;     TS_ASSERT_EQUALS( 2 * 2, 5 );&lt;br /&gt; }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Запустив этот "тест", можно увидеть:&lt;br /&gt;&lt;pre style="border: 1px solid rgb(208, 208, 208); font-family: monospace; color: black; background-color: rgb(240, 240, 240);"&gt;# ./test&lt;br /&gt;Running 2 tests.&lt;br /&gt;test.h:15: Expected (2 * 2 == 5), found (4 != 5)&lt;br /&gt;Failed 1 of 2 tests&lt;br /&gt;Success rate: 50%&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Кроме того, если передать генератору параметры &lt;span style="font-weight: bold;"&gt;--gui=Win32Gui&lt;/span&gt; или &lt;span style="font-weight: bold;"&gt;--gui=QtGui&lt;/span&gt;, то программа соберётся со страшным графическим интерфейсам из одного прогресс-бара. Мне подобное не нужно, но кому-то это может показаться удобно, например если тестов в файле много и они выполняются очень долго.&lt;br /&gt;&lt;h1&gt;Интеграция с CMake&lt;/h1&gt;&lt;br /&gt;Так как я использую &lt;a href="http://cmake.org/"&gt;CMake&lt;/a&gt; в качестве системы сборки, то прикручивать тесты буду именно к ней.&lt;br /&gt;В CMake нашелся модуль для "поиска" и использования CxxTest. Но модуль какой-то невнятный и неудобный — искать не умеет, исполняемые файлы создаёт только из получившегося после препроцессора исходного файла, то есть никаких других файлов ни прилинковать, никаких других исходников не добавить. Если тесты тянут по зависимостям функции из других файлов это недопустимо.&lt;br /&gt;В итоге я немного переделал код, найденный в wiki сайта CxxTest и получил такой макрос:&lt;br /&gt;&lt;pre style="border: 1px solid rgb(208, 208, 208); font-family: monospace; color: black; background-color: rgb(240, 240, 240);"&gt;&lt;br /&gt;SET(CXXTEST_EXECUTABLE ${PROJECT_SOURCE_DIR}/3rdparty/cxxtest/cxxtestgen.pl)&lt;br /&gt;&lt;br /&gt;MACRO(unit_test NAME CXX_FILE FILES)&lt;br /&gt;SET(PATH_FILES "")&lt;br /&gt;# Мне это не нужно, но если файлы расположены в&lt;br /&gt;# другом каталоге то может понадобиться&lt;br /&gt;#FOREACH(part ${FILES})&lt;br /&gt;#    SET(PATH_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${part}" ${PATH_FILES})&lt;br /&gt;#ENDFOREACH(part ${FILES})&lt;br /&gt;SET(PATH_FILES ${FILES})&lt;br /&gt;&lt;br /&gt;SET(CXX_FILE_REAL "${CMAKE_CURRENT_SOURCE_DIR}/${CXX_FILE}")&lt;br /&gt;SET(CXXTEST_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.cxx")&lt;br /&gt;ADD_CUSTOM_COMMAND(&lt;br /&gt;OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${NAME}.cxx"&lt;br /&gt;COMMAND ${CXXTEST_EXECUTABLE} --error-printer -o "${CXXTEST_OUTPUT}" ${CXX_FILE_REAL}&lt;br /&gt;DEPENDS "${FILE}")&lt;br /&gt;SET_SOURCE_FILES_PROPERTIES(${CXXTEST_OUTPUT} PROPERTIES GENERATED true)&lt;br /&gt;&lt;br /&gt;ADD_EXECUTABLE("${NAME}" "${CXXTEST_OUTPUT}" ${PATH_FILES})&lt;br /&gt;TARGET_LINK_LIBRARIES("${NAME}" ${CXXTEST_LINK_LIBS})&lt;br /&gt;ADD_TEST("${NAME}" "${EXECUTABLE_OUTPUT_PATH}/${NAME}")&lt;br /&gt;ENDMACRO(unit_test)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Таким макросом пользоваться удобнее. Во первых, можно задать несколько исходных файлов, не только один заголовок. Во-вторых, можно компоновать получающийся исполняемый файл любыми библиотеками, достаточно перед вызовом макроса задать переменную CXXTEST_LINK_LIBS.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Интеграция с CTest&lt;/h1&gt;&lt;br /&gt;Команда &lt;a href="http://cmake.org/cmake/help/cmake2.6docs.html#command:add_test"&gt;ADD_TEST&lt;/a&gt; в макросе добавляет тест для CTest.&lt;br /&gt;Чтобы CTest вообще работал, перед применением его команд в CMake надо вызвать &lt;a href="http://cmake.org/cmake/help/cmake2.6docs.html#command:enable_testing"&gt;ENABLE_TESTING()&lt;/a&gt;.&lt;br /&gt;Ну и для каждого заголовочного файла с тестом вызывать созданный макрос unit_test.&lt;br /&gt;После сборки проекта, можно запустить тесты несколькими способами.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;make test&lt;/span&gt; — выполняет все тесты, выводит о них Passed или Failed. Это можно вставить в скрипты сборки и не вспоминать о них пока тесты не поломаются.&lt;/li&gt;&lt;li&gt;Непосредственный запуск CTest: &lt;span style="font-weight: bold;"&gt;ctest&lt;/span&gt;, более подробный &lt;span style="font-weight: bold;"&gt;ctest -v&lt;/span&gt;  или даже &lt;span style="font-weight: bold;"&gt;ctest -vv&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;Если CMake создаёт проект для Visual Studio, то создаётся отдельный проект для тестов, который можно запустить.&lt;/li&gt;&lt;/ol&gt;Всё хорошо, всё работает, осталось только приучить себя писать тесты...&lt;br /&gt;Дополнительные материалы:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://cmake.org/cmake/help/cmake2.6docs.html"&gt;Руководство CMake&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://cmake.org/cmake/help/ctest2.6docs.html"&gt;Руководство CTest&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://cxxtest.com/guide.html"&gt;Руководство CxxTest&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-1768227286403620240?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/1768227286403620240/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2009/08/cxxtest.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/1768227286403620240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/1768227286403620240'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2009/08/cxxtest.html' title='Тестирование с помощью CxxTest'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-3240285343130569566</id><published>2009-08-13T17:05:00.003+04:00</published><updated>2009-08-13T17:55:52.277+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ликбез'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Пустые деструкторы и auto_ptr</title><content type='html'>Думал некоторое время над довольно простой вещью.&lt;br /&gt;Допустим, у нас есть некоторый класс, который объявлен заранее и используется каким-нибудь "умным" указателем:&lt;br /&gt;&lt;pre name="code" class="brush: cpp"&gt;&lt;br /&gt;class B; // forward declare&lt;br /&gt;&lt;br /&gt;class A&lt;br /&gt;{&lt;br /&gt;public:&lt;br /&gt;    A();&lt;br /&gt;private:&lt;br /&gt;    auto_ptr&amp;lt;B&gt; b;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Такое описание мы включаем в header, в cpp соответственно включаем и header, где описан B. Всё правильно, для создания указателя компилятору не нужно видеть описание класса.&lt;br /&gt;Проблема в том, что я не объявил у класса A деструктор. Так как "умные" указатели вызывают для указателя delete в своём деструкторе, нас ждёт проблема: при вызове delete компилятор должен видеть определение класса, чтобы вызвать ему деструктор или перегруженный оператор delete (если определения класса нет - получаем Undefined Behaviour, хотя например g++ показывает warning). Соответственно, если в одном из исходников, куда мы включаем свой header, включён файл с определением B, а в другой - нет, то мы прямо-таки нарываемся на нарушение &lt;a href="http://en.wikipedia.org/wiki/One_Definition_Rule"&gt;ODR&lt;/a&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Если бы в классе A был объявлен деструктор, то инстанцирование деструктора auto_ptr&amp;lt;B&amp;gt; было бы произведено там, а там у нас есть определение B.&lt;/li&gt;&lt;li&gt;Если же деструктора у A нет, то создаётся деструктор по умолчанию, который вызывает деструктор auto_ptr&amp;lt;B&amp;gt;. Но создаётся он во всех файлах, куда включён header с A. Какую потом реализацию выберет компоновщик неизвестно.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Таким образом, опять приходим к прописным истинам:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Объявлять пустые деструкторы в такой ситуации однозначно нужно.&lt;/li&gt;&lt;li&gt;Или же не выпендриваться и включать все нужные заголовки, а потом пить чай пока проект собирается.&lt;/li&gt;&lt;li&gt;Пользоваться &lt;a href="http://www.boost.org/doc/libs/1_39_0/libs/smart_ptr/scoped_ptr.htm"&gt;boost::scoped_ptr&lt;/a&gt; вместо std::auto_ptr, так как в boost проверяется, может ли компилятор удалить объект (и получаем ошибку компиляции в случае неудачи).&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-3240285343130569566?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/3240285343130569566/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2009/08/blog-post_13.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/3240285343130569566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/3240285343130569566'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2009/08/blog-post_13.html' title='Пустые деструкторы и auto_ptr'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-2522954101736607985</id><published>2009-08-12T13:37:00.001+04:00</published><updated>2009-08-13T17:57:02.472+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='g++'/><category scheme='http://www.blogger.com/atom/ns#' term='Ликбез'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='MSVS'/><title type='text'>Кодировки и BOM</title><content type='html'>Довольно забавно обстоит дело с обработкой компилятором от Microsoft строковых литералов в программах на C++. В случаях с символами, попадающими в первые 7 бит (ANSI) всё ясно - всегда всё нормально. Но с родной кириллицей всё веселее.&lt;br /&gt;И редактор студии, и компилятор умеют определять используемую кодировку. Вот только редактор делает это лучше.&lt;br /&gt;Пример: есть файлы в UTF-8 без &lt;a href="http://ru.wikipedia.org/wiki/BOM#.D0.9F.D0.BE.D1.80.D1.8F.D0.B4.D0.BE.D0.BA_.D0.B1.D0.B0.D0.B9.D1.82.D0.BE.D0.B2"&gt;BOM&lt;/a&gt;, созданные под GNU/Linux, с программой на &lt;a href="http://ru.wikipedia.org/wiki/Qt"&gt;Qt&lt;/a&gt;. g++ сохраняет кодировку в литералах и в памяти программы строка оказывается в кодировке UTF-8. И перевести её потом в QString можно при помощи &lt;a href="http://qt.nokia.com/doc/4.5/qstring.html#fromUtf8"&gt;fromUtf8&lt;/a&gt;.&lt;br /&gt;Компилятор же от Microsoft не видя BOM считает, что кодировка файла соответствует локали и тоже оставляет строковые литералы как есть. Но, так он неверно определяет кодировку, вместо unicode-литералов (это те, которые L"текст") в памяти получается мусор.&lt;br /&gt;Пример:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;MessageBox(0, L"Привет", L"Мир", MB_OK);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_joUw660-o64/SoKXXCQLTjI/AAAAAAAAAAw/TOKxGlTHjUE/s1600-h/mbox.PNG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 104px; height: 107px;" src="http://4.bp.blogspot.com/_joUw660-o64/SoKXXCQLTjI/AAAAAAAAAAw/TOKxGlTHjUE/s400/mbox.PNG" alt="" id="BLOGGER_PHOTO_ID_5369020127776558642" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Если же файл сохранить с BOM, то тогда компилятор догадывается что это UTF-8 и переводит обычные строки в локальную кодировку, зато и unicode-строки воспринимает правильно. И прощай один код для двух платформ, придётся пользоваться &lt;a href="http://qt.nokia.com/doc/4.5/qstring.html#fromLocal8Bit"&gt;fromLocal8Bit&lt;/a&gt; под Windows и fromUtf8 под GNU/Linux.&lt;br /&gt;Кроме того, g++ хоть и формально умеет работать с UTF-8, но к BOM относится враждебно, отказываясь компилировать, что опять же не позволяет использовать один исходник для обеих платформ.&lt;br /&gt;&lt;br /&gt;Вывод: либо смириться и не использовать кириллицу в исходном коде, либо не использоваться Unicode-литералы и пользоваться QString::fromUft8 везде.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Примечание&lt;/span&gt;: Стандарт не разрешает использовать национальные символы даже в литералах, вместо этого надо указывать код символа (например '\320'), так что лучше кириллицу в исходниках не использовать вовсе. С другой стороны Qt предлагает удобные утилиты и классы для перевода. Другое дело что это почти всегда неудобно, особенно когда программа пишется только для русскоязычных пользователей и возиться с переводом того что можно сразу сделать на русском не хочется.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-2522954101736607985?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/2522954101736607985/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2009/08/bom.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/2522954101736607985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/2522954101736607985'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2009/08/bom.html' title='Кодировки и BOM'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_joUw660-o64/SoKXXCQLTjI/AAAAAAAAAAw/TOKxGlTHjUE/s72-c/mbox.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-443823215471905284</id><published>2009-08-06T17:45:00.000+04:00</published><updated>2009-08-06T21:40:46.054+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Институт'/><category scheme='http://www.blogger.com/atom/ns#' term='Методички'/><category scheme='http://www.blogger.com/atom/ns#' term='MSVS'/><category scheme='http://www.blogger.com/atom/ns#' term='Office'/><title type='text'>Методички для института</title><content type='html'>В этом году я в добровольно-принудительном порядке написал две простеньких методички своему родному институту.&lt;br /&gt;Оказалось что писать - дело нелёгкое, нудное. Оказывается, писать текст и код так, чтобы было понятно даже идиоту нелегко. Слишком многое всё равно остаётся за рамками рассмотрения. Ещё сложнее совместить простоту и функциональность - да, код ещё должен выполнять задание. В общем, писатель из меня никудышный.&lt;br /&gt;&lt;br /&gt;Тем не менее, что-то всё же получилось и кому-нибудь может пригодиться.&lt;br /&gt;&lt;br /&gt;Первая методичка - про реализацию COM посредством ATL в MSVS. Тут я даже сподобился на интуитивно-понятные видеоматериалы (тут всё очень мелко, но в архиве видео с нормальным разрешением):&lt;br /&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-2d4243a9eadd4332" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v14.nonxt5.googlevideo.com/videoplayback?id%3D2d4243a9eadd4332%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331288027%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D6D351A91DC2FA82A4DA13F64869451913FBDF099.508CD5EEA19DDFB2F0E4A21080FEE175B99A00D3%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D2d4243a9eadd4332%26offsetms%3D5000%26itag%3Dw160%26sigh%3DywPWVhRLZVDQE0sDtwnEpW9SqDk&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v14.nonxt5.googlevideo.com/videoplayback?id%3D2d4243a9eadd4332%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331288027%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D6D351A91DC2FA82A4DA13F64869451913FBDF099.508CD5EEA19DDFB2F0E4A21080FEE175B99A00D3%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D2d4243a9eadd4332%26offsetms%3D5000%26itag%3Dw160%26sigh%3DywPWVhRLZVDQE0sDtwnEpW9SqDk&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-165bb6b293aed419" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v7.nonxt6.googlevideo.com/videoplayback?id%3D165bb6b293aed419%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331288027%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D4147B78B83F7E7948AE8E742EAB6F8D3D787638A.48AC7432B651722DA7C84B7768ABB897EB58F6A4%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D165bb6b293aed419%26offsetms%3D5000%26itag%3Dw160%26sigh%3DiPDnh54BGbeJp5gryiF8q0oMgrk&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v7.nonxt6.googlevideo.com/videoplayback?id%3D165bb6b293aed419%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1331288027%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D4147B78B83F7E7948AE8E742EAB6F8D3D787638A.48AC7432B651722DA7C84B7768ABB897EB58F6A4%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3D165bb6b293aed419%26offsetms%3D5000%26itag%3Dw160%26sigh%3DiPDnh54BGbeJp5gryiF8q0oMgrk&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Внутри архива - презентация, методичка, проекты к методичке и презентации, а также видео:&lt;br /&gt;&lt;a href="http://narod.ru/disk/11709967000/COM%20%D0%B8%20ATL.7z.html"&gt;Скачать методичку по COM и ATL.7z&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Вторая методичка - про автоматизацию MS Office через COM из всё той же MSVS. Тут меня уже на видео не хватило, но проекты и методичку в архиве вы найдёте:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://narod.ru/disk/11710158000/MS%20Office%20%D0%B8%D0%B7%20MSVS.7z.html"&gt;Скачать методичку по MS Office из MSVS.7z&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-443823215471905284?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=165bb6b293aed419&amp;type=video%2Fmp4' length='0'/><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=2d4243a9eadd4332&amp;type=video%2Fmp4' length='0'/><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/443823215471905284/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2009/08/blog-post_06.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/443823215471905284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/443823215471905284'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2009/08/blog-post_06.html' title='Методички для института'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2589006988873069196.post-8220089094826851091</id><published>2009-08-06T15:34:00.001+04:00</published><updated>2009-08-13T17:04:57.671+04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Debug'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='MSVS'/><title type='text'>Про переводы строк</title><content type='html'>Писал сегодня получение информации о системе в windows-части диплома. Была задача получить при помощи Windows API несколько значений и запихнуть их в QString-и, которые используются далее по коду.&lt;br /&gt;Казалось бы, что сложного? Написал вот такой код:&lt;br /&gt;&lt;pre name="code" class="brush: cpp"&gt;&lt;br /&gt;// Определяем имя компьютера&lt;br /&gt;char computerName[200]={0};&lt;br /&gt;DWORD dummy = sizeof(computerName)/sizeof(char);&lt;br /&gt;GetComputerNameA(computerName, &amp;amp;dummy);&lt;br /&gt;computer = QString::fromLocal8Bit(computerName);&lt;br /&gt;// Определяем текущий каталог&lt;br /&gt;char currentDir[400]={0};&lt;br /&gt;GetCurrentDirectoryA(sizeof(currentDir)/sizeof(char), currentDir);&lt;br /&gt;curdir = QString::fromLocal8Bit(currentDir);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Всё хорошо, всё компилируется... и ничего не показывает. В соответствующих строках - пусто.&lt;br /&gt;&lt;br /&gt;Перечитываю код - вроде всё верно, должно работать. Значит начинаем отладку.&lt;br /&gt;Отладка, как обычно, начинается с полной пересборки проекта. Rebuild - это просто обязательное действие. Оно гарантирует что мы не будем искать ошибку в неправильном коде, который слинковался в результате ошибки компоновки с приращением&lt;br /&gt;(incremental linking) или неправильно разрешенными зависимостями между файлами.&lt;br /&gt;&lt;br /&gt;Конечно же пересборка проблему не устранила. Попытка пройтись по шагам в построчном отладчике тоже ничего не дала - проект собран в release, код перемешан и указатель прыгает как бешенный по каждому F10 (Step over).&lt;br /&gt;&lt;br /&gt;Зато просмотр окна disassemble (Alt+8) выявил, что функции наши не вызываются вовсе. Как будто и нет этого кода...&lt;br /&gt;И действительно, получившийся EXE не зависит от функций GetComputerNameA , GetCurrentDirectoryA и прочих.&lt;br /&gt;&lt;br /&gt;Чтобы убедиться что в эту ветку кода вообще заходит управление, добавил перед вышеприведённым кодом&lt;br /&gt;искусственный бряк:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;__asm int 3;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Эта инструкция предназначена для останова в отладчике.&lt;br /&gt;&lt;br /&gt;Проект успешно брякнулся, значит код в этой ветке исполняется. Тут моё подозрение пало на компоновщик, и я некоторое время изучал его опции. Всё было верно.&lt;br /&gt;&lt;br /&gt;Круг подозреваемых всё более сужался. Было ясно, что что-то происходит при компиляции. Первая мысль была про неверную оптимизацию,&lt;br /&gt;но я её сразу отбросил.&lt;br /&gt;Подумав некоторое время, я стёр строку комментария "// Определяем имя компьютера".&lt;br /&gt;На моё счастье я забыл описать переменную computer выше и получил ошибку.&lt;br /&gt;Но чудо: ошибка указывала на строку с другим номером!&lt;br /&gt;&lt;br /&gt;После этого стало всё ясно:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;файл изначально писался под linux-ом и переводы строк были обычные для unix-систем (\n).&lt;/li&gt;&lt;li&gt; эту часть файла я дописывал под windows, вставив из другого файла (\r\n).&lt;/li&gt;&lt;li&gt; компилятор запутался в разных переводах строк и не посчитал за перевод строки символы после комментария. Таким образом, следующие строки считались продолжением однострочного комментария...&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Проблема решилась в меню File-&gt;Advanced Save Options указанием Line Endings и сохранением файла.&lt;br /&gt;&lt;br /&gt;Мораль:&lt;br /&gt;&lt;ol&gt;&lt;li&gt; переводы строк тоже имеют значение и могут запутать компилятор.&lt;/li&gt;&lt;li&gt; Умение пользоваться инструментарием вроде Dependency Walker или встроенного дисассемблера MSVS сильно ускоряет локализацию проблемы.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Теперь принудительная установка окончаний строк наряду с указанием кодировки в моём обязательном списке того, что надо сделать при таких необычных проблемах с компиляцией.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2589006988873069196-8220089094826851091?l=codovstvo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://codovstvo.blogspot.com/feeds/8220089094826851091/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://codovstvo.blogspot.com/2009/08/blog-post.html#comment-form' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/8220089094826851091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2589006988873069196/posts/default/8220089094826851091'/><link rel='alternate' type='text/html' href='http://codovstvo.blogspot.com/2009/08/blog-post.html' title='Про переводы строк'/><author><name>Игорь Говоров</name><uri>http://www.blogger.com/profile/15939464410626654176</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_joUw660-o64/SnsXmXaev_I/AAAAAAAAAAM/9K2DdjFG6_g/S220/photo.png'/></author><thr:total>0</thr:total></entry></feed>
