<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;Ck8EQHw5fip7ImA9WxNUGEo.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470</id><updated>2009-11-10T19:33:21.226+03:00</updated><title>Code @ C++</title><subtitle type="html">Mostly C++ programming tips, but sometimes here one can find my mind dump...</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://jia3ep.blogspot.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>89</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/CodeWorkCodeMore" type="application/atom+xml" /><feedburner:emailServiceId>CodeWorkCodeMore</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;DEMESX8_eCp7ImA9WxNUFEk.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-5690360727209550744</id><published>2009-11-05T21:10:00.006+03:00</published><updated>2009-11-05T21:40:08.140+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-05T21:40:08.140+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu" /><category scheme="http://www.blogger.com/atom/ns#" term="разное" /><title>Ubuntu 9.10 fast review</title><content type="html">Обновил Ubuntu, &lt;a href="http://superuser.com/questions/62179/should-i-reinstall-ubuntu"&gt;как и советовали&lt;/a&gt;, через неделю после выхода. Обновление прошло без проблем, но после перезагрузки оказалось, что не отображается экран входа в систему. Случайно обнаружилось, что окно логина расположилось на ТВ. Не ясно чем телек так привлек, но поведение это не удалось поменять, т.к. настройки такой не обнаружилось — все очень скромно:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/__7K5Kkk1LX0/SvMb97kr2UI/AAAAAAAABaw/_LeBN4Br2a4/s1600-h/login_sett.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 114px;" src="http://4.bp.blogspot.com/__7K5Kkk1LX0/SvMb97kr2UI/AAAAAAAABaw/_LeBN4Br2a4/s320/login_sett.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5400691128924887362" /&gt;&lt;/a&gt;&lt;br /&gt;Окно микшера сделали симпатичнее, чем было, но посмотрел я туда не из любопытства, а потому что не заработал звук через S/PDIF-&gt;HDMI. Пока не ясно как это чинить.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/__7K5Kkk1LX0/SvMZ5Mi6rFI/AAAAAAAABag/Zn6raXdlsA0/s1600-h/sound_sett.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 262px;" src="http://4.bp.blogspot.com/__7K5Kkk1LX0/SvMZ5Mi6rFI/AAAAAAAABag/Zn6raXdlsA0/s320/sound_sett.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5400688848558271570" /&gt;&lt;/a&gt;&lt;br /&gt;Зачем-то установился Network Manager, который написал, что не может управлять моими сетями. Оно и к лучшему — сеть работала отлично, как и раньше.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/__7K5Kkk1LX0/SvMaYCqsM_I/AAAAAAAABao/QI5lMFsdDHw/s1600-h/no_network.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 115px;" src="http://2.bp.blogspot.com/__7K5Kkk1LX0/SvMaYCqsM_I/AAAAAAAABao/QI5lMFsdDHw/s320/no_network.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5400689378482467826" /&gt;&lt;/a&gt;&lt;br /&gt;Попробовал новый официальный клиент обмена сообщениями Empathy. Аккаунт импортировался из Pidgin без проблем, но сообщения приходили в неправильной кодировке. Разбираться стало лень, поэтому пока остается Pidgin.&lt;br /&gt;&lt;br /&gt;Ожидаемо порадовало наличие gcc версии 4.4.1. На этом пока все и закончилось, т.к. остальное работает без замечаний и без заметных нововведений.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-5690360727209550744?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/MQzXuo6u7qw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/5690360727209550744/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=5690360727209550744" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5690360727209550744?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5690360727209550744?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/MQzXuo6u7qw/ubuntu-910-fast-review.html" title="Ubuntu 9.10 fast review" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/__7K5Kkk1LX0/SvMb97kr2UI/AAAAAAAABaw/_LeBN4Br2a4/s72-c/login_sett.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/11/ubuntu-910-fast-review.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IHSH45fip7ImA9WxNVGE4.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-5909247810050591080</id><published>2009-10-23T14:26:00.002+04:00</published><updated>2009-10-29T18:52:19.026+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-29T18:52:19.026+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Deleting incomplete type</title><content type="html">Поскольку люди стали задавать вопросы зачем вообще нужна проверка на то, что тип является полностью определенным, то разъясню этот момент подробнее.&lt;br /&gt;&lt;br /&gt;Дело в том, что стандарт в части 5.3.5/5 разрешает удаление объектов неполностью определенных типов:&lt;blockquote&gt;If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.&lt;/blockquote&gt;Продемонстрировать проблему можно на следующем простом примере:&lt;pre name="code" class="brush:cpp"&gt;struct X; // неполностью определенный тип (определяется позднее)&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; X* x = 0;&lt;br /&gt; delete x; // стандарт разрешает это&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;struct X&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt; ~X() {}; // private destructor&lt;br /&gt;};&lt;/pre&gt;Этот код компилируется несмотря на приватный деструктор, и, очевидно, этот деструктор не вызывается. В этом и есть опасность. Приличные компиляторы выдают предупреждение в этом случае, но ошибка была бы полезнее. И функция &lt;a href="http://jia3ep.blogspot.com/2009/10/useful-templates.html"&gt;&lt;tt&gt;SafeDelete&lt;/tt&gt;&lt;/a&gt; обеспечивает выдачу такой ошибки.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-5909247810050591080?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/3KVARBGdsAs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/5909247810050591080/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=5909247810050591080" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5909247810050591080?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5909247810050591080?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/3KVARBGdsAs/deleting-incomplete-type.html" title="Deleting incomplete type" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/10/deleting-incomplete-type.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UARXk6fSp7ImA9WxNVEkU.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-3235394272606199773</id><published>2009-10-23T12:00:00.000+04:00</published><updated>2009-10-23T12:07:24.715+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-23T12:07:24.715+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="template" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Useful templates</title><content type="html">В дополнение к предыдущему сообщению ещё пара полезных шаблонов:&lt;br /&gt;&lt;pre name="code" class="brush:cpp"&gt;//Безопасное удаление&lt;br /&gt;template&amp;lt;typename T&gt;&lt;br /&gt;inline void SafeDelete( T*&amp; p )&lt;br /&gt;{&lt;br /&gt;  // Проверка, что тип полностью определен&lt;br /&gt;  typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];&lt;br /&gt;  (void) sizeof(type_must_be_complete);&lt;br /&gt;  // проверять p на равенство нулю не нужно, т.к. стандарт &lt;br /&gt;  // гарантирует корректную работу delete&lt;br /&gt;  delete p;&lt;br /&gt;  p = NULL;&lt;br /&gt;}&lt;/pre&gt;Если нет запрета на использование &lt;a href="http://www.boost.org"&gt;boost&lt;/a&gt;, то лучше использовать &lt;a href="http://www.boost.org/doc/libs/1_40_0/libs/utility/checked_delete.html"&gt;boost::checked_delete&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="brush:cpp"&gt;// Безопасное удаление через Release&lt;br /&gt;template&amp;lt;typename T, typename D&gt;&lt;br /&gt;inline void SafeRelease( T*&amp; p, D d ) &lt;br /&gt;{ &lt;br /&gt;  if ( p != NULL ) {&lt;br /&gt;    (p-&gt;*d)();&lt;br /&gt;    p = NULL;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;template&amp;lt;typename T&gt;&lt;br /&gt;inline void SafeRelease( T*&amp; p) &lt;br /&gt;{ &lt;br /&gt;  return SafeRelease( p, &amp;T::Release );&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;UPD:&lt;/span&gt;22окт добавлена проверка на то, что тип является полностью определенным.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-3235394272606199773?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/-S3bxPrA130" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/3235394272606199773/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=3235394272606199773" title="Комментарии: 5" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3235394272606199773?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3235394272606199773?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/-S3bxPrA130/useful-templates.html" title="Useful templates" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/10/useful-templates.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YFQ309cCp7ImA9WxNVEEg.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-3798561998564400824</id><published>2009-10-19T14:14:00.008+04:00</published><updated>2009-10-20T21:18:32.368+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-20T21:18:32.368+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="template" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Portable way to shut up compiler warning</title><content type="html">Совсем недавно Герб Саттер (Herb Sutter) &lt;a href="http://herbsutter.wordpress.com/2009/10/18/mailbag-shutting-up-compiler-warnings/"&gt;привел пример&lt;/a&gt; портируемого способа запретить вывод предупреждений компилятора о неиспользуемых переменных. Широко используемый способ — определить макрос следующего вида:&lt;br /&gt;&lt;pre name="code" class="brush:cpp"&gt;#define UNUSED(x) x&lt;/pre&gt;Однако, этот способ не работает в некоторых компиляторах (в том смысле, что не убирает предупреждение). Саттер предлагает определить простой шаблон:&lt;br /&gt;&lt;pre name="code" class="brush:cpp"&gt;template&amp;lt;class T&gt; void ignore( T&amp; ) { }&lt;/pre&gt;Можно это определение поместить в неймспейс для избежания конфликтов, чего нельзя сделать с макросом. Следует отметить, что параметр функции &lt;tt&gt;ignore&amp;lt;T&gt;&lt;/tt&gt; следует оставить без имени, чтобы не получить предупреждение теперь уже в другом месте.&lt;br /&gt;&lt;br /&gt;Использовать шаблонную функцию довольно просто:&lt;br /&gt;&lt;pre name="code" class="brush:cpp"&gt;static void Constraints(D* p)&lt;br /&gt;{&lt;br /&gt;  B* pb = p;&lt;br /&gt;  ignore(pb); // portably suppresses the warning&lt;br /&gt;}&lt;/pre&gt;От себя хотел бы дополнить, что лучше писать так:&lt;br /&gt;&lt;pre name="code" class="brush:cpp"&gt;template&amp;lt;class T&gt; void ignore( const T&amp; ) { }&lt;/pre&gt;Это необходимо по причинам, которые обсуждались на &lt;a href="http://stackoverflow.com/questions/1565600/non-const-reference-to-temporary-object"&gt;stackoverflow.com&lt;/a&gt;.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;UPD:&lt;/span&gt;Саттер услышал замечание насчет &lt;tt&gt;const&lt;/tt&gt; и обновил свое сообщение.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-3798561998564400824?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/SW-ERlK8lyY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/3798561998564400824/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=3798561998564400824" title="Комментарии: 3" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3798561998564400824?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3798561998564400824?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/SW-ERlK8lyY/portable-way-to-shut-up-compiler.html" title="Portable way to shut up compiler warning" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/10/portable-way-to-shut-up-compiler.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4DR3Y9eCp7ImA9WxNWGEU.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-8923840422007570093</id><published>2009-10-18T20:21:00.003+04:00</published><updated>2009-10-18T20:39:36.860+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-18T20:39:36.860+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="memcpy" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Do not use &amp; for arrays</title><content type="html">Представьте, что вам попался код следующего вида:&lt;br /&gt;&lt;pre name="code" class="brush:cpp"&gt;typedef unsigned char Str255[257];&lt;br /&gt;Str255 Blah;&lt;br /&gt;&lt;br /&gt;void f( Str255 s )&lt;br /&gt;{&lt;br /&gt;  memcpy(&amp;Blah, &amp;s, sizeof(Str255)); // error here&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  Str255 x("Blah");&lt;br /&gt;  f( x );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Вопрос в том, почему данный код будет работать неверно, т.е. в Blah будет скопировано не содержимое &lt;tt&gt;x&lt;/tt&gt;, а непонятный мусор? Ошибка тут в том, что в &lt;tt&gt;memcpy&lt;/tt&gt; не нужно использовать &lt;tt&gt;&amp;&lt;/tt&gt;, а писать &lt;tt&gt;memcpy(Blah, s, sizeof(Str255));&lt;/tt&gt;. Потому что &lt;tt&gt;s&lt;/tt&gt; и &lt;tt&gt;&amp;s&lt;/tt&gt; — это разные указатели, и они даже имеют разный тип: &lt;tt&gt;unsigned char *&lt;/tt&gt; and &lt;tt&gt;unsigned char (*)[257]&lt;/tt&gt; соответсвенно. Обычно указатель на первый элемент массива и указатель на массив — это одно и тоже, но в нашем случае это не так. Посмотри как выглядит функция &lt;tt&gt;f&lt;/tt&gt;, если не использовать &lt;tt&gt;typedef&lt;/tt&gt;:&lt;br /&gt;&lt;pre name="code" class="brush:cpp"&gt;void f( unsigned char* s )&lt;br /&gt;{&lt;br /&gt;  memcpy(&amp;Blah, &amp;s, sizeof(Str255)); // error here&lt;br /&gt;}&lt;/pre&gt;При вызове этой функции, в соответсвии с пунктом 4.2 стандарта C++, массив будет неявно преобразован в указатель и мы получим, что &lt;tt&gt;s&lt;/tt&gt; указывает на массив с текстом, но &lt;tt&gt;&amp;s&lt;/tt&gt; будет указывать на указатель, который хранится на стеке, т.е. при копировании мы получим содержимое стека в &lt;tt&gt;Blah&lt;/tt&gt;. Чтобы избежать такого недоразумения лучше использовать &lt;tt&gt;std::string&lt;/tt&gt; в C++, ну а в C просто не использовать &lt;tt&gt;typedef&lt;/tt&gt; для строк и понимать что происходит.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-8923840422007570093?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/ngBWBN6WxFw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/8923840422007570093/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=8923840422007570093" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/8923840422007570093?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/8923840422007570093?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/ngBWBN6WxFw/do-not-use-for-arrays.html" title="Do not use &amp; for arrays" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/10/do-not-use-for-arrays.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8EQHw-fip7ImA9WxNWEUw.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-3978701145481074958</id><published>2009-10-09T22:30:00.003+04:00</published><updated>2009-10-09T22:43:21.256+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-09T22:43:21.256+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Best font for programming</title><content type="html">Наверное, многие уже слышали о шрифте &lt;a href="http://en.wikipedia.org/wiki/Consolas"&gt;Consolas&lt;/a&gt;. Его особенность в том, что он был разработан с нуля для использования всех преимуществ ClearType. Другие моноширинные шрифты сглаживаются операционной системой и, как правило, смотрятся размыленно со включенным ClearType. Шрифт совершенно бесплатный и может быть скачан &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3&amp;displaylang=en"&gt;тут&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Я услышал о нем не очень давно и совершенно случайно, но теперь не представляю как можно было смотреть на другие шрифты. Использую его при написании кода и в Windows и в &lt;a href="http://ubuntu.ru/get"&gt;Ubuntu&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Consolas, 10pt:&lt;br /&gt;&lt;img src="http://www.codinghorror.com/blog/images/consolas_10_cleartype.gif" border="0" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;Lucida Console, 9pt:&lt;br /&gt;&lt;img src="http://www.codinghorror.com/blog/images/lucida_9_standard.gif" border="0" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;small&gt;Шкриншоты позаимствованы с www.codinghorror.com.&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-3978701145481074958?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/ohBdKctyCMk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/3978701145481074958/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=3978701145481074958" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3978701145481074958?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3978701145481074958?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/ohBdKctyCMk/best-font-for-programming.html" title="Best font for programming" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/10/best-font-for-programming.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UGSHc_fip7ImA9WxNXFEo.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-4794922016974415265</id><published>2009-10-02T11:59:00.004+04:00</published><updated>2009-10-02T12:13:49.946+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-02T12:13:49.946+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="template" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Determining 32 vs 64 bit in C++</title><content type="html">Для реализации некоторых операций, которые зависят от битности платформы, часто используют директивы препроцессора. Однако, существует проблема с переносимостью такого кода, т. к. в стандарте нет макросов, которые помогают идентифицировать битность платформы.&lt;br /&gt;&lt;br /&gt;Можно попробовать решить такую задачу на этапе компиляции. Шаблоны дают все возможности для этого и код остается переносимым.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="brush:cpp"&gt;template&amp;lt;int&gt; void DoMyOperation();&lt;br /&gt;&lt;br /&gt;template&amp;lt;&gt; void DoMyOperation&amp;lt;4&gt;() &lt;br /&gt;{&lt;br /&gt;  // do 32-bits operations&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template&amp;lt;&gt; void DoMyOperation&amp;lt;8&gt;() &lt;br /&gt;{&lt;br /&gt;  // do 64-bits operations&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt;  // appropriate function will be selected at compile time &lt;br /&gt;  DoMyOperation&amp;lt;sizeof(size_t)&gt;(); &lt;br /&gt;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;В примере выше использован тип &lt;tt&gt;size_t&lt;/tt&gt;, но стандарт говорит только о том, что этот тип должен уметь хранить максимальный размер блока памяти в текущей реализации системы аллоцирования. Строго говоря, это только косвенно говорит о том скольки битная платформа используется, но сложно представить себе реализацию С++, где это будет неприменимо.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-4794922016974415265?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/31G-X5DkqrE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/4794922016974415265/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=4794922016974415265" title="Комментарии: 2" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/4794922016974415265?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/4794922016974415265?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/31G-X5DkqrE/determining-32-vs-64-bit-in-c.html" title="Determining 32 vs 64 bit in C++" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/10/determining-32-vs-64-bit-in-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYBR3g4eyp7ImA9WxNXFEU.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-3383807294380718770</id><published>2009-09-30T21:10:00.007+04:00</published><updated>2009-10-02T16:22:36.633+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-02T16:22:36.633+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="разное" /><title>Microsoft Innovation Day осень 2009</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://picasaweb.google.com/lh/photo/QFBJHrYhsj41T7buOXNyBA?authkey=Gv1sRgCIzd7dGBxdaVdw&amp;feat=embedwebsite"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 162px; height: 200px;" src="http://lh5.ggpht.com/__7K5Kkk1LX0/SsPD2NydS0I/AAAAAAAAA9E/DKr0shdFbyo/s144/%24SCN1022.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5387367414759397042" /&gt;&lt;/a&gt;Вчера прошел традиционный форум компаний разработчиков Microsoft Innovation Day. На этот раз веб-разработчиков выделили в отдельную секцию, поэтому секций было три. Я посетил техническую. &lt;br /&gt;&lt;br /&gt;На технической секции немного рассказали о том, что Windows 7 выходит, но так как об этом и так все знают, то особенно на это не задерживались. Упомянули только, что есть Platform Update для Windows XP и Windows Vista, который добавляет некоторые возможности новой ОС (&lt;a href="http://blogs.technet.com/isv_team/archive/2009/09/11/3280586.aspx"&gt;подробнее...&lt;/a&gt;). &lt;br /&gt;&lt;br /&gt;Очень поверхностно рассказали о новых продуктах семейства Office 2010, а также SQL Server 2008 R2. В Office ожидается веб варианты компонентов офиса как аналог &lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt;, но доступны они будут через корпоративный Share Point сервер, что и понятно &amp;mdash; все-таки они не бесплатные. Это видится как очередной шаг к сервисам в облаке.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://picasaweb.google.com/lh/photo/dVv6J6XckzcHH3I6hQ5M8g?authkey=Gv1sRgCIzd7dGBxdaVdw&amp;feat=embedwebsite"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 150px;" src="http://lh3.ggpht.com/__7K5Kkk1LX0/SsPD2ZTKo_I/AAAAAAAAA9I/sZgY0DeHPpM/s144/%24SCN1024.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5387367583412208098" /&gt;&lt;/a&gt;В SQL Server 2008 R2 интерес представляет новая технология StreamInsight. Но о ней рассказали не очень подробно и понятно (я так и не понял, можно ли будет хранить видео в БД), однако есть первоисточник где можно почитать об этом &lt;a href="http://www.microsoft.com/sqlserver/2008/en/us/R2-complex-event.aspx"&gt;подробнее&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Для компаний разработчиков может оказаться интересным, что программа &lt;a href="https://partner.microsoft.com/rus/licensing/licensingprograms/ltvolumelicensing/vlisvroyaltylicensing"&gt;ISV Royalty&lt;/a&gt; теперь работает через российских представителей и не нужно покупать лицензии в Ирландии как раньше. Также снят нижний предел закупок для участия в этой акции.&lt;br /&gt;&lt;br /&gt;В конце показали ролик с представлением Microsoft о будущем Office 2019:&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/nq3EeZz-W3A&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=ru&amp;feature=player_embedded&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/nq3EeZz-W3A&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=ru&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Судя по видео у нас в 2019 году будут не whiteboards, а transparentboards, что не очень удобно на мой взгляд :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-3383807294380718770?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/b2_45k0I960" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/3383807294380718770/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=3383807294380718770" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3383807294380718770?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3383807294380718770?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/b2_45k0I960/microsoft-innovation-day-2009.html" title="Microsoft Innovation Day осень 2009" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/__7K5Kkk1LX0/SsPD2NydS0I/AAAAAAAAA9E/DKr0shdFbyo/s72-c/%24SCN1022.JPG" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/09/microsoft-innovation-day-2009.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MBSXo9cSp7ImA9WxNQEko.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-2686552323914600768</id><published>2009-09-18T15:54:00.005+04:00</published><updated>2009-09-18T16:04:18.469+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-18T16:04:18.469+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>integer types</title><content type="html">Стандарт C'99 ISO подразумевает наличие файла &lt;tt&gt;stdint.h&lt;/tt&gt; с определением типов, которые полезны для портируемых программ или описания форматов сетевых пакетов (типы вроде &lt;tt&gt;uint8_t&lt;/tt&gt; и &lt;tt&gt;int64_t&lt;/tt&gt; и так далее...). Поскольку Visual C++ 2008 не поддерживает полностью стандарт С99, то там этого файла нет. Если же пользоваться этими типами хочется, то можно использовать портируемую версию этого хедера — &lt;a href="http://www.azillionmonkeys.com/qed/pstdint.h"&gt;pstdint.h&lt;/a&gt;, которая распространяется под BSD лицензией, т.е. даром.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-2686552323914600768?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/Ol8M6k3Wk-c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/2686552323914600768/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=2686552323914600768" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/2686552323914600768?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/2686552323914600768?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/Ol8M6k3Wk-c/interger-types.html" title="integer types" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/09/interger-types.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQDQXw4fip7ImA9WxNQEUo.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-8516305900458299028</id><published>2009-09-17T11:26:00.000+04:00</published><updated>2009-09-17T11:26:10.236+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-17T11:26:10.236+04:00</app:edited><title>Официальный блог - Google Россия: Объявляем о начале регистрации заявок на участие в Google Developer Day 2009 в Москве</title><content type="html">&lt;a href="http://googlerussiablog.blogspot.com/2009/09/google-developer-day-2009.html"&gt;Официальный блог - Google Россия: Объявляем о начале регистрации заявок на участие в Google Developer Day 2009 в Москве&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-8516305900458299028?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/TiTJNukPPIY" height="1" width="1"/&gt;</content><link rel="related" href="http://googlerussiablog.blogspot.com/2009/09/google-developer-day-2009.html" title="Официальный блог - Google Россия: Объявляем о начале регистрации заявок на участие в Google Developer Day 2009 в Москве" /><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/8516305900458299028/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=8516305900458299028" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/8516305900458299028?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/8516305900458299028?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/TiTJNukPPIY/google-google-developer-day-2009.html" title="Официальный блог - Google Россия: Объявляем о начале регистрации заявок на участие в Google Developer Day 2009 в Москве" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/09/google-google-developer-day-2009.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UDR3w-fCp7ImA9WxNSFEU.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-2310692112629031958</id><published>2009-08-28T22:45:00.002+04:00</published><updated>2009-08-28T22:47:56.254+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-28T22:47:56.254+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="boost" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>boost 1.40</title><content type="html">Тихо и незаметно вчера вышла очередная версия библиотеки boost. &lt;a href="http://www.boost.org/users/news/version_1_40_0"&gt;Список изменений&lt;/a&gt; небольшой, в основном затронута библиотека &lt;a href="http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio.html"&gt;Asio&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-2310692112629031958?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/cK5rgarjhlg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/2310692112629031958/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=2310692112629031958" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/2310692112629031958?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/2310692112629031958?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/cK5rgarjhlg/boost-140.html" title="boost 1.40" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/08/boost-140.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cHRHo_eCp7ImA9WxNQEUU.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-7308454528152237063</id><published>2009-08-28T21:55:00.007+04:00</published><updated>2009-09-17T14:57:15.440+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-17T14:57:15.440+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="GNOME" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu" /><title>Changing wallpaper on Linux programmatically</title><content type="html">Для тех, кто хочет начать работать с GNOME, но не знает с чего начать, вот задачка &amp;mdash; поменять обои рабочего стола. Это я так пытаюсь подойти к проблеме поддержки разных обоев для двух мониторов (точнее, монитора и HD телевизора в моем случае). В KDE с этим проблем нет, но в GNOME такой настройки нет. Оказалось, что сделать это несложно. Проблемой я собирался заняться давно, но преодолеть лень и написать код меня сподвигнул &lt;a href="http://stackoverflow.com/questions/1220826/changing-wallpaper-on-linux-programmatically"&gt;этот вопрос&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Нам понадобятся: Ubuntu, любимый текстовый редактор, пакет build-essentials, libglib-2.0-dev, libgconf2-dev и консоль. Думаю, что ставить пакеты все умеют (кто не умеет &amp;mdash; читать &lt;a href="https://help.ubuntu.com/6.10/ubuntu/serverguide/ru/apt-get.html"&gt;тут&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;В текстовом редакторе создаем файл следующего содержания:&lt;pre name="code" class="brush:cpp"&gt;// bkgmanage.c&lt;br /&gt;#include &amp;lt;glib.h&gt;&lt;br /&gt;#include &amp;lt;gconf/gconf-client.h&gt;&lt;br /&gt;#include &amp;lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;typedef enum {&lt;br /&gt;    WALLPAPER_ALIGN_TILED     = 0,&lt;br /&gt;    WALLPAPER_ALIGN_CENTERED  = 1,&lt;br /&gt;    WALLPAPER_ALIGN_STRETCHED = 2,&lt;br /&gt;    WALLPAPER_ALIGN_SCALED    = 3,&lt;br /&gt;    WALLPAPER_NONE            = 4&lt;br /&gt;} WallpaperAlign;&lt;br /&gt;&lt;br /&gt;gboolean set_as_wallpaper( const gchar *image_path, WallpaperAlign align )&lt;br /&gt;{&lt;br /&gt;    GConfClient *client;&lt;br /&gt;    char        *options = "none";&lt;br /&gt;&lt;br /&gt;    client = gconf_client_get_default();&lt;br /&gt;&lt;br /&gt;    // TODO: проверить, что image_path является файлом и вообще существует&lt;br /&gt;    if ( image_path == NULL ) options = "none";&lt;br /&gt;    else {&lt;br /&gt;        gconf_client_set_string( client, &lt;br /&gt;            "/desktop/gnome/background/picture_filename",&lt;br /&gt;            image_path,&lt;br /&gt;            NULL );&lt;br /&gt;        switch ( align ) {&lt;br /&gt;            case WALLPAPER_ALIGN_TILED: options = "wallpaper"; break;&lt;br /&gt;            case WALLPAPER_ALIGN_CENTERED: options = "centered"; break;&lt;br /&gt;            case WALLPAPER_ALIGN_STRETCHED: options = "stretched"; break;&lt;br /&gt;            case WALLPAPER_ALIGN_SCALED: options = "scaled"; break;&lt;br /&gt;            case WALLPAPER_NONE: options = "none"; break;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    gboolean result = gconf_client_set_string( client, &lt;br /&gt;        "/desktop/gnome/background/picture_options", &lt;br /&gt;        options,&lt;br /&gt;        NULL);&lt;br /&gt;    g_object_unref( G_OBJECT(client) );&lt;br /&gt;&lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, const char* argv[])&lt;br /&gt;{&lt;br /&gt;  if ( argc &gt; 1 ) {&lt;br /&gt;    printf( "Setting %s as wallpaper... ", argv[1] );&lt;br /&gt;    if ( set_as_wallpaper( argv[1], WALLPAPER_ALIGN_STRETCHED ) ) printf( "Ok\n" );&lt;br /&gt;    else printf( "Failed\n" );&lt;br /&gt;  } else printf( "Usage: ./bkgmanage &amp;lt;filename&gt;\n" );&lt;br /&gt;&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;&lt;a href=http://library.gnome.org/devel/gconf/stable/&gt;gconf&lt;/a&gt; &amp;mdash; это библиотека для управлением аналогом реестра в GNOME. С помощью неё и исправляется параметр &lt;tt&gt;/desktop/gnome/background/picture_filename&lt;/tt&gt; для замены картинки, а также &lt;tt&gt;/desktop/gnome/background/picture_options&lt;/tt&gt; для определения параметров отображения этой картинки. Изменения вступают в силу мгновенно.&lt;br /&gt;&lt;br /&gt;Сборка указанного выше файла тоже не составляет труда. Достаточно в консоли ввести:&lt;pre&gt;gcc -Wall -g `pkg-config --libs --cflags glib-2.0 gconf-2.0` bkgmanage.c -o bkgmanage&lt;/pre&gt;Тут &lt;span style="font-style:italic;"&gt;pkg-config&lt;/span&gt; возвращает все необходимые пути к include-файлам и библиотеки, необходимые для линковки, что очень удобно. В результате получается исполняемый файл &lt;span style="font-style:italic;"&gt;bkgmanage&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Далее, остается сделать GUI для удобного выбора картинок для каждого монитора с последующей склейкой в один файл. Пока не решил какой фреймворк для этого выбрать &amp;mdash; основная идея, что хочется писать на С++, но Qt имеет слишком много зависимостей, которые в GNOME по умолчанию отсутствуют...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-7308454528152237063?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/9hCnncWeXgc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/7308454528152237063/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=7308454528152237063" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/7308454528152237063?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/7308454528152237063?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/9hCnncWeXgc/changing-wallpaper-on-linux.html" title="Changing wallpaper on Linux programmatically" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/08/changing-wallpaper-on-linux.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MFSHc5fCp7ImA9WxJaFU4.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-6735766040836839016</id><published>2009-08-06T10:06:00.004+04:00</published><updated>2009-08-06T10:16:59.924+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-06T10:16:59.924+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Trigraph sequences in C++</title><content type="html">C++ стандарт в части 2.3/1 утверждает, что перед началом любой обработки кода все вхождения трех символов, указанных в таблице, будут заменены на один соответствующий символ.&lt;br /&gt;&lt;pre&gt;----------------------------------------------------------------------------&lt;br /&gt;| trigraph | replacement | trigraph | replacement | trigraph | replacement |&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;| ??=      | #           | ??(      | [           | ??&lt;      | {           |&lt;br /&gt;| ??/      | \           | ??)      | ]           | ??&gt;      | }           |&lt;br /&gt;| ??’      | ˆ           | ??!      | |           | ??-      | ˜            |&lt;br /&gt;----------------------------------------------------------------------------&lt;/pre&gt;На практике это означает, что если даже в строковой константе встретится такая последовательность, то последствия могут оказаться неожиданными. Например, такой код:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;printf( "What??!\n" )&lt;/code&gt;&lt;/pre&gt;Выдаст пользователю такой текст:&lt;br /&gt;&lt;pre&gt;What|&lt;/pre&gt;Помимо этого есть такая же таблица для пар символов, которая делает следующий код вполне корректной программой на С++:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;%:include &amp;lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;%:ifndef BUFSIZE&lt;br /&gt; %:define BUFSIZE  512&lt;br /&gt;%:endif&lt;br /&gt;&lt;br /&gt;void copy(char d&amp;lt;::&gt;, const char s&amp;lt;::&gt;, int len)&lt;br /&gt;&amp;lt;%&lt;br /&gt;    while (len-- &gt;= 0)&lt;br /&gt;    &amp;lt;%&lt;br /&gt;        d&amp;lt;:len:&gt; = s&amp;lt;:len:&gt;;&lt;br /&gt;    %&gt;&lt;br /&gt;%&gt;&lt;/code&gt;&lt;/pre&gt;Стандарт поддерживает эти символы для совместимости, т.к. на очень старом железе в Европе не было части символов. Интересно, что в будущем стандарте С+x0 было предложено отказаться от поддержки триграфов, однако, этого видимо не произойдет. Подробнее &lt;a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2910.pdf"&gt;тут&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Для современных разработчиков пользы это этой фичи языка C++ толку никакого, но знать и помнить о ней нужно, чтобы понимать что происходит.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-6735766040836839016?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/-JIeC1UBFzM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/6735766040836839016/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=6735766040836839016" title="Комментарии: 2" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/6735766040836839016?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/6735766040836839016?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/-JIeC1UBFzM/trigraph-sequences-in-c_06.html" title="Trigraph sequences in C++" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/08/trigraph-sequences-in-c_06.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUARXw4eCp7ImA9WxNQEUU.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-7528020207653373716</id><published>2009-07-13T00:45:00.002+04:00</published><updated>2009-09-17T14:44:04.230+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-17T14:44:04.230+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>работаем с Windows Registry</title><content type="html">Для восстановления веток реестра в Windows существует функция &lt;tt&gt;RegRestoreKey&lt;/tt&gt;. До Windows Vista ей можно было свободно пользоваться для восстановления, например, настроек по умолчанию программы. В Windows Vista это стало требовать поднятия уровня процесса(elevation) с появлением назойливого диалога UAC. Конечно, понятно, что большинство читающих эту статью живут с отключенным UAC, но подавляющее большинство обычных пользователей(по данным Microsoft) UAC не выключают. У &lt;tt&gt;RegRestoreKey&lt;/tt&gt; есть ещё один недостаток &amp;mdash; она работает с файлами в бинарном формате, который отличается для каждой новой версии ОС.&lt;br /&gt;&lt;br /&gt;Однако, существует в Windows и программа &lt;tt&gt;reg.exe&lt;/tt&gt;, которая имеет встроенный парсер REG-фалов. Да, именно тех, которые описывают ключи в обычном тектовом формате. Команды import и export этой утилиты не требуют каких либо повышенных прав. Конечно, здесь речь идет о разделах &lt;tt&gt;HKCU&lt;/tt&gt;. Почему эти функции не выделили в отдельный API остается загадкой.&lt;br /&gt;&lt;br /&gt;Ниже приведен пример использования этой утилиты в программе:&lt;pre class="brush:cpp"&gt;// Получаем указатель на REG файл прилинковынный в ресурсы&lt;br /&gt;HRSRC hRsrc = ::FindResource( NULL, MAKEINTRESOURCE(IDR_DEFSETTINGS), L"REG" ); // IDR_DEFSETTINGS - идентификатор ресурса с файлом. Может быть другим.&lt;br /&gt;HGLOBAL hGlobal = ::LoadResource( NULL, hRsrc );&lt;br /&gt;LPVOID lpReg = ::LockResource( hGlobal );&lt;br /&gt;&lt;br /&gt;// Сохраняем во временный файл&lt;br /&gt;wchar_t path_buf[MAX_PATH];&lt;br /&gt;SHGetFolderPath( NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, &amp;path_buf[0] );&lt;br /&gt;const wstring temp_filename = path_buf+L"\\temp_reg.reg";&lt;br /&gt;ofstream os( temp_filename.c_str(), ios_base::binary );&lt;br /&gt;os.write( static_cast&amp;lt;char*&gt;(lpReg), ::SizeofResource( NULL, hRsrc ) );&lt;br /&gt;os.close();&lt;br /&gt;&lt;br /&gt;// Готовим параметры reg.exe.&lt;br /&gt;wstring params( L"import \"");&lt;br /&gt;params += temp_filename;&lt;br /&gt;params += L"\""; // Путь к файлу должен быть в кавычках на случай пробелов&lt;br /&gt;&lt;br /&gt;// Запускаем reg.exe&lt;br /&gt;SHELLEXECUTEINFO se = {0};&lt;br /&gt;se.cbSize = sizeof SHELLEXECUTEINFO;&lt;br /&gt;se.fMask = SEE_MASK_NOCLOSEPROCESS|SEE_MASK_UNICODE;&lt;br /&gt;se.hwnd = GetSafeHwnd();&lt;br /&gt;se.lpFile = L"reg.exe"; // находится в system32, поэтому путь указывать необязательно&lt;br /&gt;se.lpParameters = params.c_str();&lt;br /&gt;se.nShow = SW_HIDE; // Смотреть на консольку пользователю ни к чему&lt;br /&gt;if ( ShellExecuteEx( &amp;se ) ) {&lt;br /&gt;  WaitForSingleObject( se.hProcess, INFINITE ); // хотя тут и написано INFINITE, но в реальной жизни лучше указать таймаут&lt;br /&gt;  CloseHandle( se.hProcess );&lt;br /&gt;} else {&lt;br /&gt; // Ошибка запуска. Как-то обрабатываем эту ситуацию.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Удаляем временный файл&lt;br /&gt;_wremove( temp_filename.c_str() );&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-7528020207653373716?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/TkDrZmIzfFc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/7528020207653373716/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=7528020207653373716" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/7528020207653373716?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/7528020207653373716?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/TkDrZmIzfFc/windows-registry.html" title="работаем с Windows Registry" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/07/windows-registry.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUDRno_eyp7ImA9WxJVGUk.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-5319023799866468625</id><published>2009-07-07T10:25:00.002+04:00</published><updated>2009-07-07T10:31:17.443+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-07T10:31:17.443+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="books" /><title>Windows Intenals 5-th</title><content type="html">&lt;table width=100%&gt;&lt;td width=20%&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=conwo-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0735625301&amp;fc1=000000&amp;IS2=1&amp;lt1=_top&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr&amp;nou=1" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;/td&gt;&lt;td valign=top&gt;Наконец-то вышло пятое издание &lt;a href=http://www.amazon.com/dp/0735625301?tag=conwo-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0735625301&amp;adid=1A5YKRFP025WH2VHPNPE&amp;&gt;Windows Internals&lt;/a&gt; и уже почтальон везет его ко мне :) Книга потолстела на 250 страниц, как пишет Марк Руссинович(Mark Russinovich) у себя в &lt;a href="http://blogs.technet.com/markrussinovich/"&gt;блоге&lt;/a&gt;. Были добавлены главы посвященные Hyper-V, Kernel Transaction Manager, Code Integrity, Thread Pools, Mandatory Integrity Controls, Windows Driver Framework и ещё немного об утилитах SysInternals. До конца года обещается 6-е издание, которое пополнеет ещё на 100 страниц и будет содержать информацию специфичную для Windows 7 и Windows Server 2008 R2.&lt;br /&gt;&lt;/td&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-5319023799866468625?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/8CBJSd3QWV8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/5319023799866468625/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=5319023799866468625" title="Комментарии: 2" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5319023799866468625?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5319023799866468625?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/8CBJSd3QWV8/windows-intenals-5-th.html" title="Windows Intenals 5-th" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/07/windows-intenals-5-th.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8FRn89eCp7ImA9WxJVFUw.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-8164616616048204087</id><published>2009-07-02T10:27:00.002+04:00</published><updated>2009-07-02T10:40:17.160+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-02T10:40:17.160+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>hex to long</title><content type="html">Как думаете, чем конвертировать шестнадцатиричную строку в 32-х битное знаковое целое? Порывшись в стандарной библиотеке можно найти функцию &lt;tt&gt;strtol&lt;/tt&gt;. И все работает обычно... до тех пор пока входные данные беззнаковые. Попробуйте конвертировать -1 (0xFFFFFFFF) и ничего не выйдет. &lt;tt&gt;strtol&lt;/tt&gt; решит, что было переполнение и вернет &lt;tt&gt;MAX_LONG&lt;/tt&gt;. Чтобы обойти эту особенность, следует использовать функцию &lt;tt&gt;strtoul&lt;/tt&gt;. Она конвертит строку в беззнаковое целое, а уж потом можно его приравнять к long и старший бит укажет знак.&lt;br /&gt;&lt;br /&gt;Пример:&lt;pre&gt;&lt;code&gt;#include &amp;lt;cstdlib&gt;&lt;br /&gt;#include &amp;lt;iostream&gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main() { &lt;br /&gt; string s = "FFFFFFFF";&lt;br /&gt; char * p;&lt;br /&gt; long n = strtoul( s.c_str(), &amp;p, 16 ); &lt;br /&gt; // overflow when using long n = strtol( s.c_str(), &amp;p, 16 ); &lt;br /&gt; if ( * p != 0 ) {  &lt;br /&gt;  cout &amp;lt;&amp;lt; "not a number" &amp;lt;&amp;lt; endl;  &lt;br /&gt; }    else {  &lt;br /&gt;  cout &amp;lt;&amp;lt; n &amp;lt;&amp;lt; endl; // prints -1&lt;br /&gt; }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-8164616616048204087?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/S0sr-OTNpRY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/8164616616048204087/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=8164616616048204087" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/8164616616048204087?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/8164616616048204087?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/S0sr-OTNpRY/hex-to-long.html" title="hex to long" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/07/hex-to-long.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQCSX8-fip7ImA9WxJWGUg.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-7513251923953618403</id><published>2009-06-25T23:11:00.005+04:00</published><updated>2009-06-25T23:32:48.156+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-25T23:32:48.156+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="разное" /><title>7 (Seven)</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/__7K5Kkk1LX0/SkPQzFT_QxI/AAAAAAAAAxI/ZYq8SkI-0dg/s1600-h/w7.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 240px; height: 219px;" src="http://1.bp.blogspot.com/__7K5Kkk1LX0/SkPQzFT_QxI/AAAAAAAAAxI/ZYq8SkI-0dg/s320/w7.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5351350358264202002" /&gt;&lt;/a&gt;Был сегодня в Microsoft'е. Из интересного &amp;mdash; сертификация под Windows 7 теперь бесплатна. Как получить лого за один день(при должном упорстве) можно посмотреть &lt;a href="http://blogs.technet.com/isv_team/archive/2009/06/24/3258198.aspx"&gt;тут&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Еще выдали интересные книжки «Обеспечение совместимости приложений с Windows 7 &amp;mdash; пособие для разработчиков» (&lt;a href="http://download.microsoft.com/documents/rus/windows/V7DEV.pdf"&gt;PDF версия&lt;/a&gt;) и «Обеспечение совместимости приложений в Microsoft Windows Vista и Windows 7 &amp;mdash; Руководство для IT-специалистов» (&lt;a href="http://download.microsoft.com/documents/rus/windows/V7IT.pdf"&gt;PDF версия&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;По мелочам: VS2010 Beta 2 выйдет до конца года, а Windows 7 уже проходит сертификацию в силовых ведомствах.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-7513251923953618403?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/bBgPXr1puIk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/7513251923953618403/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=7513251923953618403" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/7513251923953618403?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/7513251923953618403?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/bBgPXr1puIk/7.html" title="7 (Seven)" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/__7K5Kkk1LX0/SkPQzFT_QxI/AAAAAAAAAxI/ZYq8SkI-0dg/s72-c/w7.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/06/7.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMFRnk9fyp7ImA9WxJWGEs.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-5717148875813799542</id><published>2009-06-24T20:47:00.003+04:00</published><updated>2009-06-24T20:53:37.767+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-24T20:53:37.767+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="favorites" /><category scheme="http://www.blogger.com/atom/ns#" term="разное" /><title>Немного ссылок</title><content type="html">Не все программисты умеют рисовать. Для них существует &lt;a href="http://www.iconfinder.net"&gt;www.iconfinder.net&lt;/a&gt;. Большинство иконок там используют лицензии GPL, LGPL, CC или Free. Можно задать поиск по ключевым словам и размерам.&lt;br /&gt;&lt;br /&gt;Ещё можно искать картинки похожие на те, что где-то увидели. На сайте &lt;a href="http://tineye.com/"&gt;tineye.com&lt;/a&gt; можно загрузить свою картинку и найти похожие с лучшим качеством. Похоже, что поиск работает.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-5717148875813799542?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/pALeWcAfVNA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/5717148875813799542/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=5717148875813799542" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5717148875813799542?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5717148875813799542?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/pALeWcAfVNA/blog-post_24.html" title="Немного ссылок" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/06/blog-post_24.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cGQnY9fyp7ImA9WxJWFU0.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-3684041678565498069</id><published>2009-06-20T18:41:00.002+04:00</published><updated>2009-06-20T18:43:43.867+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-20T18:43:43.867+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="разное" /><title>Семинар Microsoft</title><content type="html">Microsoft проводит последний(до выхода Windows 7) однодневный семинар посвященный обсуждению вопросов обеспечения совместимости приложений. Семинар пройдет в Москве 25-го июня. По &lt;a href="http://www.microsoft.com/rus/events/detail.mspx?eventid=1032418128"&gt;ссылке &lt;/a&gt;можно ещё успеть зарегистрироваться.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-3684041678565498069?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/x1Mq8hRrLuM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/3684041678565498069/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=3684041678565498069" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3684041678565498069?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3684041678565498069?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/x1Mq8hRrLuM/microsoft.html" title="Семинар Microsoft" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/06/microsoft.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8GRnw_cSp7ImA9WxJWFU0.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-3161073284150589513</id><published>2009-06-20T18:33:00.003+04:00</published><updated>2009-06-20T18:40:27.249+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-20T18:40:27.249+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="template" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>x or X and stackoverflow.com</title><content type="html">Некоторое время назад я &lt;a href="http://jia3ep.blogspot.com/2008/03/x-x.html"&gt;писал&lt;/a&gt; о том как можно проверить наличие той или иной переменной в структуре или классе. Оказалось, что оба описанных метода некорректны с точки зрения стандарта. Решение было получено на страницах сайта stackoverflow.com, который был организован Джоелом Спольски(Joel Spolsky) и Джефом Атвудом(Jeff Atwood). Само решение можно посмотреть &lt;a href="http://stackoverflow.com/questions/1005476/how-to-detect-whether-xbig-x-or-xsmall-x-in-class/1007175#1007175"&gt;тут&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Рекомендую обращаться к страницам указанного сайта тем, кто этого ещё не делает. Там бывают интересные вопросы и ответы.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-3161073284150589513?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/QWKzoSaHNjY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/3161073284150589513/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=3161073284150589513" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3161073284150589513?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3161073284150589513?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/QWKzoSaHNjY/x-or-x-and-stackoverflowcom.html" title="x or X and stackoverflow.com" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/06/x-or-x-and-stackoverflowcom.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEGQXs5fCp7ImA9WxJXFUs.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-6882038729760673654</id><published>2009-06-09T21:27:00.002+04:00</published><updated>2009-06-09T21:30:20.524+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-09T21:30:20.524+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="debug" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Хозяйке на заметку</title><content type="html">Следующий метод отладки имеет весьма узкое применение и в большинстве случаев может оказатся неподходящим. Описанное решение пришло в результате поиска проблемы в чужом коде, написанном в ужасном стиле (смесь С++ и С). Речь пойдет о защите памяти с помощью функции &lt;tt&gt;VirtualProtect&lt;/tt&gt;. Эта функция позволяет изменить режим доступа к страницам памяти: только чтение, копирование по записи, полное отсутсвие доступа и далее. Полный список флагов можно найти в &lt;a href=http://msdn.microsoft.com/en-us/library/aa366786(VS.85).aspx&gt;документации&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Для целей отладки интересен флаг &lt;tt&gt;PAGE_NOACCESS&lt;/tt&gt;. Он позволяет ловить запись или, что более важно, чтение за пределами некоторой валидной области памяти. Для удобного применения &lt;tt&gt;VirtualProtect&lt;/tt&gt; был создан следующий класс:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;struct protect_mem_t {&lt;br /&gt;    protect_mem_t( void* addr, size_t size ) : addr(addr), size(size), is_protected(FALSE) { &lt;br /&gt;        protect(); &lt;br /&gt;    }&lt;br /&gt;    ~protect_mem_t() { release(); }&lt;br /&gt;    BOOL protect() { &lt;br /&gt;        if ( !is_protected ) {&lt;br /&gt;            is_protected = VirtualProtect( addr, size, PAGE_NOACCESS, &amp;old_protect );&lt;br /&gt;        }&lt;br /&gt; return is_protected;&lt;br /&gt;    }&lt;br /&gt;    BOOL release() { &lt;br /&gt;        if ( is_protected ) &lt;br /&gt;            is_protected = !VirtualProtect( addr, size, old_protect, &amp;old_protect );&lt;br /&gt; return !is_protected;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;protected:&lt;br /&gt;    void*   addr;&lt;br /&gt;    size_t  size;&lt;br /&gt;    BOOL    is_protected;&lt;br /&gt;    DWORD   old_protect;&lt;br /&gt;};&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Применять его можно следующим образом:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;const size_t PAGE_SIZE = 4096;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; const size_t var_size = 1024*96; // 1024*96 - некоторый размер. Конкретное значение здесь только в качестве примера.&lt;br /&gt; const size_t guard_size = PAGE_SIZE*2-var_size%PAGE_SIZE;&lt;br /&gt; __declspec(align(4096)) char some_var[var_size+guard_size];&lt;br /&gt; protect_mem_t guard( &amp;some_var[var_size], PAGE_SIZE );&lt;br /&gt;&lt;br /&gt; some_var[5] = 20;   // that's ok&lt;br /&gt; char x = some_var[5];   // that's ok&lt;br /&gt; &lt;br /&gt; char y = some_var[1024*96+1024]; // access violation&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;В приведенном примере, как и в реальной программе, была добавлена защитная область памяти прямо на стеке. Удачной отладки.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-6882038729760673654?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/6annI4h3-EI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/6882038729760673654/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=6882038729760673654" title="Комментарии: 2" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/6882038729760673654?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/6882038729760673654?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/6annI4h3-EI/blog-post.html" title="Хозяйке на заметку" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/06/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IDRHo-cCp7ImA9WxJQFkw.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-3755652105931657754</id><published>2009-05-29T21:24:00.003+04:00</published><updated>2009-05-29T21:52:55.458+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-29T21:52:55.458+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Бывет и такое...</title><content type="html">Казалось бы проблемы из-за сравнения знаковых и беззнаковых значений давно известны и обходятся опытными разработчиками. Однако, разработчики компилятора Microsoft C++, который входит в состав Visual Studio 2008 SP1 сделали такую ошибку, которая и была (не без удивления) обнаружена у нас в компании. Код, который позволяет воспроизвести эту ошибку приведен ниже:&lt;pre&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; for ( int k = -4; k &lt; -1; k++ ) {&lt;br /&gt;  unsigned long kkk = (k+4)*8+1;&lt;br /&gt;  bool jjj = kkk &amp;lt; 256;&lt;br /&gt;  if ( jjj == false ) cout &amp;lt;&amp;lt; "Impossible!!!" &amp;lt;&amp;lt; endl;&lt;br /&gt; }&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;Если скомпилировать такой код с ключом /O2(&lt;tt&gt;cl /EHsc /O2 main.cpp&lt;/tt&gt;), то будет выведен текст, который не должен быть выведен. Если без ключа оптимизации(&lt;tt&gt;cl /EHsc main.cpp&lt;/tt&gt;), то текст не будет выведен.&lt;br /&gt;&lt;br /&gt;Проблема тут в том, что компилятор оптимизурет выражение &lt;tt&gt;(k+4)*8+1 &lt; 256&lt;/tt&gt; до &lt;tt&gt;k &lt; 28&lt;/tt&gt;, забывая что &lt;tt&gt;k&lt;/tt&gt; может принимать отрицательные значения и результат сравнения проверяет командой, которая знак не учитывает.&lt;br /&gt;&lt;br /&gt;Нечасто приходится сталкиваться с такими ошибками и страшно подумать, где в коде это может проявится. Последить за судьбой этого бага в багтрекере Майкрософт можно &lt;a href=https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=460715&gt;тут&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-3755652105931657754?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/RWHAVgOdhSg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/3755652105931657754/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=3755652105931657754" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3755652105931657754?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/3755652105931657754?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/RWHAVgOdhSg/blog-post.html" title="Бывет и такое..." /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/05/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4BQXY5eip7ImA9WxJQE0s.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-6882877248749709935</id><published>2009-05-22T23:22:00.009+04:00</published><updated>2009-05-26T22:02:30.822+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-26T22:02:30.822+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="boost" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>ordered_unique vs hashed_unique</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/__7K5Kkk1LX0/Shb9K5SYzCI/AAAAAAAAAlg/eMNSPujw0eQ/s1600-h/boost.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 120px; height: 70px;" src="http://4.bp.blogspot.com/__7K5Kkk1LX0/Shb9K5SYzCI/AAAAAAAAAlg/eMNSPujw0eQ/s320/boost.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5338732771912764450" /&gt;&lt;/a&gt;Контейнер multi_index библиотеки boost поддерживает несколько типов индексов. Среди них есть два очень похожих &amp;mdash; ordered index и hashed index. Разница ясна из названия, hashed index не гарантирует какого-либо порядка сортировки, что, по идее, делает его несколько быстрее. Именно это и утверждается в документации: «they provide much faster lookup of elements, at the expense of losing sorting information». Что означает «much faster» далее не раскрывается.&lt;br /&gt;&lt;br /&gt;Для того, чтобы выяснить эту разницу в скорости, можно создать следующую структуру, которая будет содержать несколько полей. Эти поля в дальнейшем будут использованы в индексации:&lt;pre&gt;&lt;code&gt;struct container_t {&lt;br /&gt;    complex_elem_t      hashed_index;&lt;br /&gt;    complex_elem_t      ordered_index;&lt;br /&gt;&lt;br /&gt;    explicit container_t() : hashed_index(), ordered_index() {};&lt;br /&gt;};&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Тип  &lt;tt&gt;complex_elem_t&lt;/tt&gt; введен для простой генерации уникальных элементов. Этот класс состоит из 5-ти полей типа &lt;tt&gt;short int&lt;/tt&gt;, что позволило сгенерировать 10 млн. элементов без коллизий. В нем присутствуют операторы == и &amp;lt;. Также пришлось создать функцию &lt;tt&gt;hash_value&lt;/tt&gt;, т.к. boost не умеет считать хэш для таких сложных структур.&lt;br /&gt;&lt;br /&gt;Тип контейнера имеет следующий вид:&lt;pre&gt;&lt;code&gt;typedef multi_index_container&amp;lt;&lt;br /&gt;  container_t,&lt;br /&gt;    indexed_by&amp;lt;&lt;br /&gt;      hashed_unique&amp;lt; member&amp;lt;container_t, complex_elem_t, &amp;container_t::hashed_index&amp;gt; &amp;gt;,&lt;br /&gt;      ordered_unique&amp;lt; member&amp;lt;container_t, complex_elem_t, &amp;container_t::ordered_index&amp;gt; &amp;gt; &amp;gt;&lt;br /&gt;  &amp;gt; containers_t;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;В своих тестах я заполнял контейнеры элементами количеством от 1 до 10млн. штук. Для каждого производилось несколько поисков и результат усреднялся. Для замеров времени использовалась инструкция процессора &lt;a href=http://ru.wikipedia.org/wiki/Rdtsc&gt;rdtsc&lt;/a&gt;. Полностью тестовую программу можно скачать &lt;a href=http://docs.google.com/View?id=dhpfgvtf_31d726hrfq&gt;тут&lt;/a&gt;. Для построения графиков использовался &lt;a href=http://ru.openoffice.org/&gt;OpenOffice&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/__7K5Kkk1LX0/ShwqUL3F-3I/AAAAAAAAAmw/HCsL17foWVo/s1600-h/hash_vs_order.png"&gt;&lt;img style="float:right; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 178px;" src="http://4.bp.blogspot.com/__7K5Kkk1LX0/ShwqUL3F-3I/AAAAAAAAAmw/HCsL17foWVo/s320/hash_vs_order.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5340189784424184690" /&gt;&lt;/a&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/__7K5Kkk1LX0/ShwuGhMT5EI/AAAAAAAAAm4/3YMWzxfDUws/s1600-h/hash_vs_order_zoom.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 178px;" src="http://4.bp.blogspot.com/__7K5Kkk1LX0/ShwuGhMT5EI/AAAAAAAAAm4/3YMWzxfDUws/s320/hash_vs_order_zoom.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5340193947678663746" /&gt;&lt;/a&gt;&lt;br /&gt;На графиках видно, что поиск в ordered index происходит за логарифм, а в hashed index за константу. По X показан размер контейнера, по Y &amp;mdash; нормированное количество тактов процессора (измерения проводились на Core2Duo E6420).&lt;br /&gt;&lt;br /&gt;Так что, если какой-либо порядок элементов не требуется, то имеет смысл использовать hashed индекс, вместо ordered.&lt;br /&gt;&lt;br /&gt;UPD: В первый раз не учитывались коллизии при вставке элементов и, поэтому, &lt;a href=http://4.bp.blogspot.com/__7K5Kkk1LX0/Shb7wsY5FdI/AAAAAAAAAlY/Jr-85kUmoI8/s1600-h/indexes.jpg&gt;старый график&lt;/a&gt; был верен только до отметки в ~180 элементов из-за &lt;a href=http://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D1%80%D0%B0%D0%B4%D0%BE%D0%BA%D1%81_%D0%B4%D0%BD%D0%B5%D0%B9_%D1%80%D0%BE%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F&gt;парадокса дней рождения&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-6882877248749709935?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/yvj0XXdqQxQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/6882877248749709935/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=6882877248749709935" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/6882877248749709935?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/6882877248749709935?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/yvj0XXdqQxQ/orderedunique-vs-hashedunique.html" title="ordered_unique vs hashed_unique" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/__7K5Kkk1LX0/Shb9K5SYzCI/AAAAAAAAAlg/eMNSPujw0eQ/s72-c/boost.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/05/orderedunique-vs-hashedunique.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MCSX0-fyp7ImA9WxJRFUo.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-6081154582820001412</id><published>2009-05-17T15:54:00.004+04:00</published><updated>2009-05-17T19:51:08.357+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-17T19:51:08.357+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="разное" /><title>Мир IT кардинально меняется?</title><content type="html">В ответ на &lt;a href=http://bishop-it.ru/2009/05/netbooks/&gt;вопрос Олега&lt;/a&gt; о том, что "Мир IT кардинально меняется."&lt;br /&gt; &lt;br /&gt;Мы разрабатываем системы безопасности. На первый взгляд - это, как правило, изолированное решение на промышленных серверах и никаких "облаков". Однако, мы уже рассматривали возможность работы в Windows Azure, поэтому далее речь об облаках от Microsoft.&lt;br /&gt;&lt;br /&gt;Уже сейчас можно отметить несколько моментов:&lt;br /&gt;1. Дата центров в России с такой ОС пока нет. Постройка самого дата центра стоит половину миллиарда долларов. Всего дата центров у Микрософт около 20 и новых они вроде пока не планируют строить. А при повсеместном переходе "в облака" дата центров нужно будет очень много. Все это займет явно больше 5 лет.&lt;br /&gt;2. Цена интернета должна быть сопоставима с ценой электричества. Ну все к этому идет, правда не только со стороны уменьшения цены интернета.&lt;br /&gt;3. Цена аренды сервиса должна быть очень низкой. Объявленная Микрософтом оказалось предварительно вполне приемлемой.&lt;br /&gt;&lt;br /&gt;Первый пункт самый нереалистичный. Несмотря не него, мы уже движемся в сторону "облачных" вычислений и, когда они будут реальны, мы будем готовы. Имеется ввиду, что вся предварительная обработка первичных данных будет идти на специализированном железе, которое работает без ОС или с Embedded версиями. А пост обработка может производится "в облаке", что позволит сократить траты на обслуживание и расширение вычислительных центров. И поддержка готового продукта будет проще без сомнений. Аналогичная схема подойдет для большинства IT-проектов. Распространение "облаков" для IT-компаний видится вовсе не плохим трендом, кроме тех, которые продают вторичные услуги.&lt;br /&gt;&lt;br /&gt;Так, опасения писателей антивирусов можно сравнить с опасением автотехцентров из-за того, что автомобили перестанут ломаться. Антивирусы вторичный продукт. Пользователи покупают компьютеры, не для того, чтобы вирусы ловить, также, как и автомобили не для того, чтобы ездить в сервис центры. Поэтому панику не стоит разводить :)&lt;br /&gt;&lt;br /&gt;При этом, мне кажется, что вирусы в Azure можно будет писать не сложнее, чем в Windows. Просто Windows самая популярная ОС и вирусы пишут именно под ней. Будет популярна другая, но люди продолжать лазить по сомнительным сайтам и заражать вирусами не свои компьютеры, а целые "облака", как сейчас заражают корпоративные сети.&lt;br /&gt;&lt;br /&gt;Интересно отметить, что уязвимыми становятся не конкретные машины пользователей, а целые дата центры. Тут возможна и угроза атак террористов. Поэтому остро встанет вопрос охраны этих дата центров физически.&lt;br /&gt;&lt;br /&gt;А с C++ ничего плохого не случится. Уже сейчас Microsoft продолжила развитие MFC и планирует развивать его в Windows 7. И в Azure он тоже никуда не денется. Т.е. от идеи повсеместного перехода на C# отказались. Ну и сам С++ не стоит на месте. А разработчика остается развиваться вместе с технологиями и все будет в порядке.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-6081154582820001412?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/btUzVNT70Kc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/6081154582820001412/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=6081154582820001412" title="Комментарии: 5" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/6081154582820001412?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/6081154582820001412?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/btUzVNT70Kc/it.html" title="Мир IT кардинально меняется?" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/05/it.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUARH45fyp7ImA9WxJSFk0.&quot;"><id>tag:blogger.com,1999:blog-5744154463195670470.post-5265368333367647869</id><published>2009-05-06T00:15:00.004+04:00</published><updated>2009-05-06T13:47:25.027+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-06T13:47:25.027+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="boost" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Другие стороны boost::format</title><content type="html">Библиотека boost::format предоставляет удобный и безопасный(по сравнению с printf) способ форматирования строк. Возможен как классический printf-стиль:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;cout &amp;lt;&amp;lt; format("writing %s,  x=%s : %d-th step \n") % "toto" % 40.23 % 50;&lt;/code&gt;&lt;/pre&gt;Так и другие, более гибкие способы форматирования, как, например, такой:&lt;pre&gt;&lt;code&gt;cout &amp;lt;&amp;lt; format("%1% %2% %3% %2% %1% \n") % "11" % "22" % "333"; // 'simple' style.&lt;/code&gt;&lt;/pre&gt;Самая очевидная проблема с printf &amp;mdash; это то, что мы должны точно указать размер каждого аргумента. Например, для &lt;tt&gt;time_t&lt;/tt&gt; в одних случаях писать &lt;tt&gt;%I64d&lt;/tt&gt;, а в других &lt;tt&gt;%d&lt;/tt&gt;. У &lt;tt&gt;time_t&lt;/tt&gt; разный размер может быть и на 32-х битной платформе в зависимости от компилятора. И это только один пример. С boost::format такие проблемы исключаются.&lt;br /&gt;&lt;br /&gt;Подробнее по всем возможностям можно посмотреть в &lt;a href=http://www.boost.org/doc/libs/1_38_0/libs/format/doc/format.html&gt;документации&lt;/a&gt;. Но речь сейчас не о возможностях boost::format , а о том как их применить у себя в программе. Мне кажется, что очень удобно было бы, например, писать информацию в лог файл без предварительного форматирования строки на стеке. Т.е. писать вместо:&lt;pre&gt;&lt;code&gt;string msg = str( boost::format("Debug message %s") % some_msg_string );&lt;br /&gt;log( msg );&lt;/code&gt;&lt;/pre&gt;вот такую строку:&lt;pre&gt;&lt;code&gt;log("Debug message %s") % some_msg_string;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Добиться этого не сложно. Нужно, всего лишь, перегрузить оператор %. Для этого создадим класс &lt;tt&gt;formatted_log_t&lt;/tt&gt;. А ещё функцию &lt;tt&gt;log&lt;/tt&gt;, которая возвращает экземпляр этого класса. Класс будет содержать в себе экземпляр boost::format.&lt;pre&gt;&lt;code&gt;#include &amp;lt;sstream&amp;gt;&lt;br /&gt;#include &amp;lt;boost/format.hpp&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;class formatted_log_t {&lt;br /&gt;public:&lt;br /&gt;    formatted_log_t(const wchar_t* msg ) : fmt(msg) {}&lt;br /&gt;    ~formatted_log_t() { wcout &amp;lt;&amp;lt; fmt &amp;lt;&amp;lt; endl; }&lt;br /&gt;    &lt;br /&gt;    template &amp;lt;typename T&amp;gt;&lt;br /&gt;    formatted_log_t&amp; operator %(T value) {&lt;br /&gt;        fmt % value;&lt;br /&gt;        return *this;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;protected:&lt;br /&gt;    boost::wformat                fmt;&lt;br /&gt;};&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Оператор % должен быть шаблонным так как мы не знаем типы форматируемых аргументов. Функция &lt;tt&gt;log&lt;/tt&gt; будет иметь следующий вид:&lt;pre&gt;&lt;code&gt;formatted_log_t log(const wchar_t* msg)&lt;br /&gt;{&lt;br /&gt;    return formatted_log_t( msg );&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;На этом месте реализация функции уже является вполне работоспособной. Далее можно добавлять какие-то другие фичи. Например, фильтр по уровню сообщений. Для этого сделаем функцию и класс шаблонными. Вот так:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;#include &amp;lt;sstream&amp;gt;&lt;br /&gt;#include &amp;lt;boost/format.hpp&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;enum log_level_t {&lt;br /&gt;    LOG_NOTHING,&lt;br /&gt;    LOG_CRITICAL,&lt;br /&gt;    LOG_ERROR,&lt;br /&gt;    LOG_WARNING,&lt;br /&gt;    LOG_INFO,&lt;br /&gt;    LOG_DEBUG&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template&amp;lt;int level&amp;gt;&lt;br /&gt;class formatted_log_t {&lt;br /&gt;public:&lt;br /&gt;    formatted_log_t(const wchar_t* msg ) : fmt(msg) {}&lt;br /&gt;    ~formatted_log_t() {&lt;br /&gt;        // GLOBAL_LEVEL is a global variable and could be changed at runtime&lt;br /&gt;        if ( level &amp;lt;= GLOBAL_LEVEL ) wcout &amp;lt;&amp;lt; fmt &amp;lt;&amp;lt; endl;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    template &amp;lt;typename T&amp;gt;&lt;br /&gt;    formatted_log_t&amp; operator %(T value) {&lt;br /&gt;        fmt % value;&lt;br /&gt;        return *this;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;protected:&lt;br /&gt;    boost::wformat                fmt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;template &amp;lt;int level&amp;gt;&lt;br /&gt;formatted_log_t&amp;lt;level&amp;gt; log(const wchar_t* msg)&lt;br /&gt;{&lt;br /&gt;    return formatted_log_t&amp;lt;level&amp;gt;( msg );&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Применять этот код можно так:&lt;pre&gt;&lt;code&gt;int main ()&lt;br /&gt;{&lt;br /&gt;    log&amp;lt;LOG_DEBUG&amp;gt;(L"TEST %3% %2% %1%") % 5 % 10 % L"privet";&lt;br /&gt;    return 0;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Работа с логом, наверное, самое очевидно, но только одно из возможных применений синтаксиса boost::format и далее можно развивать эту идею как вам больше нравится.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5744154463195670470-5265368333367647869?l=jia3ep.blogspot.com'/&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CodeWorkCodeMore/~4/xjPEulfO1Go" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://jia3ep.blogspot.com/feeds/5265368333367647869/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5744154463195670470&amp;postID=5265368333367647869" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5265368333367647869?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5744154463195670470/posts/default/5265368333367647869?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/CodeWorkCodeMore/~3/xjPEulfO1Go/boostformat.html" title="Другие стороны boost::format" /><author><name>jia3ep</name><uri>http://www.blogger.com/profile/03118738824565485127</uri><email>jia3ep@gmail.com</email><gd:extendedProperty name="OpenSocialUserId" value="00017758575482446373" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://jia3ep.blogspot.com/2009/05/boostformat.html</feedburner:origLink></entry></feed>
