<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>typedef</title>
	
	<link>http://typedef.ru</link>
	<description>Сан Саныч о программировании, технологиях, Computer Science и вообще.</description>
	<lastBuildDate>Sat, 13 Mar 2010 11:03:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Typedef" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="typedef" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Переменное число аргументов в функциях C</title>
		<link>http://typedef.ru/2010/03/varying-argument-count-in-c-functions/</link>
		<comments>http://typedef.ru/2010/03/varying-argument-count-in-c-functions/#comments</comments>
		<pubDate>Sat, 13 Mar 2010 11:01:59 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=530</guid>
		<description><![CDATA[Полезная, но редко используемая и часто недопонимаемая возможность языка C &#8212; переменное число аргументов функции. Это такая особая сишная магия, позволяющая писать функции наподобие printf(). Обычно такие функции пишутся именно для форматированного вывода текста, хотя возможны и другие применения. В учебниках любят приводить в качестве примера функцию сложения произвольного числа аргументов, но вряд ли такое [...]]]></description>
			<content:encoded><![CDATA[<p>Полезная, но редко используемая и часто недопонимаемая возможность языка C &#8212; переменное число аргументов функции. Это такая особая сишная магия, позволяющая писать функции наподобие <code>printf()</code>. Обычно такие функции пишутся именно для форматированного вывода текста, хотя возможны и другие применения. В учебниках любят приводить в качестве примера функцию сложения произвольного числа аргументов, но вряд ли такое можно увидеть в реальном коде.</p>
<p>Выглядеть определение такой безразмерной функции может как-то так (три точки в списке формальных аргументов следует воспринимать буквально, то есть там именно три точки):</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> myfunct<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> arg1<span style="color: #339933;">,</span> <span style="color: #993333;">double</span> arg2<span style="color: #339933;">,</span> ...<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #808080; font-style: italic;">/* какой-то код */</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Так как в языке C обычно придерживаются <a href="http://en.wikipedia.org/wiki/X86_calling_conventions" target="_blank">соглашения о вызовах cdecl</a>, то аргументы, передаваемые функции, передаются через стек, причем кладутся туда, начиная с последнего (правого) аргумента и заканчивая первым. Вот вам примерный портрет стекового фрейма для вызова функции с N аргументами на процессоре x86:</p>
<p style="text-align: center;"><a title="Стековый фрейм" rel="lightbox[pics530]" href="http://typedef.ru/wp-content/uploads/2010/02/call_stack.png"><img class="attachment wp-att-551 centered" src="http://typedef.ru/wp-content/uploads/2010/02/call_stack.png" alt="Стековый фрейм" width="375" height="500" /></a></p>
<p>Все наши знания о фрейме ограничены значениями регистров ESP и EBP. Та точка отсчета, от которой мы можем отталкиваться для доступа к аргументам &#8212; текущее значение регистра EBP. Например, первый аргумент лежит по адресу EBP+8, а второй &#8212; по адресу EBP+12. Ладно, а сколько нужно прибавить к EBP, чтобы получить адрес N-го аргумента в стеке? Для этого нужно знать:</p>
<ul>
<li>сколько всего передано аргументов;</li>
<li>размеры аргументов (кто сказал, что они должны быть одинаковы?).</li>
</ul>
<p>Ни то, ни другое в доступных нам ESP и EBP не хранится. Знаем мы только то, что именованные аргументы имеют меньшие адреса. Выходит, что размеры аргументов должны быть жестко определены в теле функции или же получены на основе значений именованных аргументов. Но как определить их количество? Рассчитывать на форматную строку, как в <code>printf</code>? Но кто гарантирует, что эта строка правильная?</p>
<p>Что, страшно уже? К счастью, всю низкоуровневую рутину с жоглированием указателями и размерами готов взять на себя компилятор, предоставляя нам удобный интерфейс в заголовочном файле <code>stdarg.h</code>. Правда, количество аргументов и их типы нам все-таки придется выяснять самостоятельно.</p>
<p>Правила нехитрые:</p>
<ul>
<li>функция должна иметь по крайней мере один именованный параметр (именованные идут в списке формальных параметров перед неименованными);</li>
<li>перед доступом к аргументам нужно вызвать <code>va_start</code>, чтобы инициализировать объект контекста (<code>va_list</code>);</li>
<li>используем <code>va_arg</code> для последовательного доступа к неименованным аргументам;</li>
<li>по окончанию вызываем <code>va_end</code> в той же функции, что и <code>va_start</code>.</li>
</ul>
<p>Тут не обойтись без примера. Посмотрим на пресловутую функцию сложения нескольких чисел (спокойствие, дальше будет более жизненный пример).</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;stdarg.h&gt;</span>
<span style="color: #993333;">int</span> sum<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> count<span style="color: #339933;">,</span> ...<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    va_list args<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> total <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
    va_start<span style="color: #009900;">&#40;</span>args<span style="color: #339933;">,</span> count<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>count<span style="color: #339933;">--</span><span style="color: #009900;">&#41;</span>
        total <span style="color: #339933;">+=</span> va_arg<span style="color: #009900;">&#40;</span>args<span style="color: #339933;">,</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    va_end<span style="color: #009900;">&#40;</span>args<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> total<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> sum<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">33</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> sum<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">4</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Пояснения здесь излишни. Кстати, <code>va_list</code> можно передавать в качестве аргумента другой функции. Надо только не забыть вызвать для него <code>va_end</code> в той же функции (а точнее, в том же вызове функции), где был вызван <code>va_start</code>. Не знаю точно, что делает <code>va_end</code>, но если он манипулирует значением EBP, то лучше бы это значение было тем же, что и раньше.</p>
<p>Зачем может понадобиться передача <code>va_list</code>? Обычно для написания оберток для функций семейства <code>printf</code>, например, в каком-нибудь логгере:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> msgOut<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">enum</span> msgLevel level<span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>fmt<span style="color: #339933;">,</span> ...<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    va_list ap<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> ret<span style="color: #339933;">;</span>
    va_start<span style="color: #009900;">&#40;</span>ap<span style="color: #339933;">,</span> fmt<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ret <span style="color: #339933;">=</span> msgOutL<span style="color: #009900;">&#40;</span>level<span style="color: #339933;">,</span> fmt<span style="color: #339933;">,</span> ap<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    va_end<span style="color: #009900;">&#40;</span>ap<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> ret<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">int</span> msgOutL<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">enum</span> msgLevel level<span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>fmt<span style="color: #339933;">,</span> va_list vl<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>level <span style="color: #339933;">&gt;=</span> s_level<span style="color: #009900;">&#41;</span>
        <span style="color: #b1b100;">return</span> vfprintf<span style="color: #009900;">&#40;</span>s_stream <span style="color: #339933;">?</span> s_stream <span style="color: #339933;">:</span> stdout<span style="color: #339933;">,</span> fmt<span style="color: #339933;">,</span> vl<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">else</span>
        <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Напоследок хочется сказать вот что. Если вы пишете функцию с переменным числом аргументов не от нечего делать, а в реальном проекте, то использование <code>stdarg.h</code> &#8212; единственный вариант. Организация стека в x86, описанная выше, &#8212; это штука, на постоянство которой не стоит рассчитывать. Оптимизирующие компиляторы могут организовать передачу аргументов через регистры, а уж про перенос программы на другие платформы и говорить не приходится. Еще одна рекомендация &#8212; пишите такие функции <em>только</em> для форматирования текста. Другие применения обычно создают больше проблем, чем решают.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2010/03/varying-argument-count-in-c-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Наши инструменты</title>
		<link>http://typedef.ru/2010/03/our-instruments/</link>
		<comments>http://typedef.ru/2010/03/our-instruments/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 20:46:38 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[идеи]]></category>
		<category><![CDATA[продуктивность]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=556</guid>
		<description><![CDATA[В последнее время меня завалил настолько мощный поток текучки, что не остается времени даже на самое необходимое, не говоря уже о блоге. Но не переживайте, у меня на стадии «почти завершено» находится несколько постов, так что в ближайшее время постараюсь создать здесь видимость жизни.
Сегодняшний пост будет короткий, но мысль, которую я здесь озвучу, очень важная. [...]]]></description>
			<content:encoded><![CDATA[<p>В последнее время меня завалил настолько мощный поток текучки, что не остается времени даже на самое необходимое, не говоря уже о блоге. Но не переживайте, у меня на стадии «почти завершено» находится несколько постов, так что в ближайшее время постараюсь создать здесь видимость жизни.</p>
<p>Сегодняшний пост будет короткий, но мысль, которую я здесь озвучу, очень важная. По крайней мере, мне так кажется. Вот она:</p>
<blockquote><p><strong>Наши инструменты только тогда максимально повышают эффективность нашей работы, когда мы перестаем их замечать.</strong></p></blockquote>
<p>Утверждение это совсем простое и даже, не побоюсь этого слова, очевидное. Понятно, что если мы за рулем машины задумываемся о том, на какую скорость нам нужно переключиться, то ни о каком водительском мастерстве и речи быть не может. Сначала мы осваиваем управление, сознательно давая себе команды сделать то или иное действие: нажать педаль, включить поворотник, переключить скорость. Со временем эти действия доводятся до автоматизма и мы перестаем о них думать. Теперь наша голова может быть занята, например, поиском оптимального маршрута до работы, выбором наиболее быстрой полосы на дороге или хватанием пассажирки за коленку. Органы управления машиной &#8212; наш инструмент &#8212; стали как бы продолжением нашего тела, и позволяют нам выполнять нужные действия, не задумываясь о них.</p>
<p>Не нравится пример с машиной? Те же соображения верны для игры на пианино, занятий виндсерфингом, боевых искусств&#8230;</p>
<p>Недавно я стал ощущать примерно то же самое при программировании, после того как полностью перешел на Emacs в качестве замены всех IDE. Да, непросто запомнить комбинацию из трех-четырех, а то и более клавиш. Часто для нужных действий нет сочетаний клавиш, а иногда нет даже и встроенной возможности выполнять эти действия. Тогда я трачу кучу времени, ищу в Сети дополнения, правлю их напильником, вешаю некоторые действия на клавиши, потом несколько дней к ним привыкаю &#8212; и все. Больше я об этих действиях не думаю. Они выполняются сами, без моего участия.</p>
<p>Например, чтобы увеличить ширину текущего окна на 20 символов, я нажимаю <code>Ctrl-u 2 0 Ctrl-x Shift-]</code>. В общей сложности 8 клавиш. Я их набираю одним движением, не задумываясь, что это такое там делают мои пальцы. Когда я писал этот абзац, мне даже пришлось потратить некоторое время, чтобы осознать, что же именно я при этом нажимаю. В общем, полнейший автоматизм.</p>
<p>А вот с мышью автоматизм не вырабатывается. Нельзя вслепую ткнуть куда-то курсором &#8212; в этом процессе всегда участвует сознание. Сначала нужно увидеть некий визуальный маркер (кнопку, пункт меню), затем подвести туда курсор, используя обратную связь через глаза для точного позиционирования, затем щелкнуть кнопкой. Одним кликом часто дело не ограничивается, поэтому повторяем все снова. Так как в этом процессе участвует сознание, из кратковременной памяти вытесняются важные сведения. Эффективность падает.</p>
<p>Конечно, я все это говорю не про мышь и не про клавиатуру. И не про Emacs. И я не хочу ни за что агитировать и ни к чему призывать. Я просто хочу сделать вывод &#8212; следствие из утверждения из начала поста:</p>
<blockquote><p><strong>Для повышения эффективности следует пользоваться инструментами, допускающими бессознательное их использование.</strong></p></blockquote>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2010/03/our-instruments/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ссылки для C-гиков</title>
		<link>http://typedef.ru/2010/02/c-geek-links/</link>
		<comments>http://typedef.ru/2010/02/c-geek-links/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 09:07:35 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=540</guid>
		<description><![CDATA[Такая вот подборка в дополнение к опубликованному ранее:

C @ Interview Mantra &#8212; подборка задач на C, предлагаемых на собеседованиях.
C Puzzles &#8212; набор сишных головоломок, неплохо прокачивает знание тонких моментов языка.
C Extensions &#8212; описание того, что GCC привносит в C помимо требований стандарта.
Coroutines in C &#8212; статья о реализации сопрограмм на C.
How to Use the restrict [...]]]></description>
			<content:encoded><![CDATA[<p>Такая вот подборка в дополнение к <a href="http://typedef.ru/2009/09/c-info-links/" target="_blank">опубликованному ранее</a>:</p>
<ul>
<li><a href="http://www.interviewmantra.net/category/interview-questions/c" target="_blank">C @ Interview Mantra</a> &#8212; подборка задач на C, предлагаемых на собеседованиях.</li>
<li><a href="http://www.gowrikumar.com/c/" target="_blank">C Puzzles</a> &#8212; набор сишных головоломок, неплохо прокачивает знание тонких моментов языка.</li>
<li><a href="http://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/C-Extensions.html" target="_blank">C Extensions</a> &#8212; описание того, что GCC привносит в C помимо требований стандарта.</li>
<li><a href="http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html" target="_blank">Coroutines in C</a> &#8212; статья о реализации <a href="http://en.wikipedia.org/wiki/Coroutine" target="_blank">сопрограмм</a> на C.</li>
<li><a href="http://developers.sun.com/solaris/articles/cc_restrict.html" target="_blank">How to Use the restrict Qualifier</a> &#8212; что такое квалификатор restrict и когда его нужно использовать.</li>
<li><a href="http://voodoo-slide.blogspot.com/2010/01/amplifying-c.html" target="_blank">Ampifying C</a> &#8212; совершенно сносящая крышу статья, описывающая применение генерации C-кода из Lisp-кода.</li>
</ul>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2010/02/c-geek-links/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Экономим свое время в bash</title>
		<link>http://typedef.ru/2010/01/time-saving-in-bash/</link>
		<comments>http://typedef.ru/2010/01/time-saving-in-bash/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 21:17:04 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[хитрости]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=515</guid>
		<description><![CDATA[Хотя даже само по себе использование bash дает нам преимущество в скорости выполнения многих рутинных задач, нужно всегда стремиться к совершенству и выжимать максимум из своих инструментов. Кому-то, возможно, покажется не очень удачной идея тратить свое время сейчас, чтобы потенциально сэкономить его потом. Но в действительности сейчас вы тратите время один раз, чтобы потом много [...]]]></description>
			<content:encoded><![CDATA[<p>Хотя даже само по себе использование bash дает нам преимущество в скорости выполнения многих рутинных задач, нужно всегда стремиться к совершенству и выжимать максимум из своих инструментов. Кому-то, возможно, покажется не очень удачной идея тратить свое время <em>сейчас</em>, чтобы потенциально сэкономить его <em>потом</em>. Но в действительности сейчас вы тратите время <em>один раз</em>, чтобы потом <em>много раз</em> его экономить</p>
<p>У меня по этому поводу всплыла в памяти одна цитата:</p>
<blockquote><p>Программист за два часа может написать программу, которая за две секунды сделает то, что обычный пользователь будет делать полчаса.</p></blockquote>
<p>На первый взгляд, такой программист напрасно тратит свое время. Но посмотрим на это с другой стороны. Если за неделю потребуется выполнить задачу пять раз, то программист (в сравнении с пользователем) сэкономит почти полчаса. А поскольку ему не придется отвлекаться от текущих дел, то экономия в действительности будет даже больше.</p>
<p>Так вот bash (и я вслед за ним) исповедует как раз такую философию: <strong>затраченные однажды усилия не должны затрачиваться снова</strong>. Ниже я приведу несколько советов, которые в рамках этого подхода позволяют иногда сэкономить несколько секунд. Мелочь, но с миру по нитке&#8230;</p>
<h4>CDPATH</h4>
<p>Переменная окружения CDPATH является аналогом переменной PATH с той разницей, что вторая определяет пути поиска исполняемых файлов, а первая — пути поиска каталогов, задаваемых в команде <code>cd</code>.</p>
<p>Если CDPATH не установлена, то поиск происходит только в текущем каталоге.</p>
<p>Обычно соответствующая строка в <code>~/.bash_profile</code> выглядит как-то так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">CDPATH</span>=.:~:~<span style="color: #000000; font-weight: bold;">/</span>Dropbox:~<span style="color: #000000; font-weight: bold;">/</span>dload:~<span style="color: #000000; font-weight: bold;">/</span>wspace</pre></div></div>

<p>Теперь, например, если в каталоге <code>~/dload</code> есть подкаталог <code>bibl</code>, то каким бы ни был текущий каталог, команда <code>cd bibl</code> приведет нас в <code>~/dload/bibl</code>.</p>
<p>Поиск в каталогах, указанных в CDPATH, происходит в том порядке, в котором они указаны в этой переменной. Поэтому обычно первым каталогом в CDPATH указывают текущий (точка), потому что в противном случае поиск в текущем каталоге будет выполняться после всех каталогов из CDPATH, что вряд ли кто-то сочтет разумным.</p>
<h4>alias</h4>
<p>Команда <code>alias</code> позволяет создать псевдоним — короткое имя для любой команды или их последовательности. Чтобы создать псевдоним, нужно выполнить:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #007800;">name</span>=<span style="color: #ff0000;">&quot;command&quot;</span></pre></div></div>

<p>Где, понятное дело, <code>name</code> — имя псевдонима, а <code>command</code> — что нужно выполнить, когда мы набираем в консоли <code>name</code>. Например:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #007800;">pa</span>=<span style="color: #ff0000;">&quot;ps -A | grep&quot;</span></pre></div></div>

<p>дает нам новую команду <code>pa</code>, с помощью которой удобно искать процессы по части их имени. Обычно все вызовы alias записываются в файле <code>~/.bashrc</code>.</p>
<p>Команда <code>unalias</code> выполняет обратное действие, то есть уничтожает указанные псевдонимы. Ключ <code>-a</code> предписывает удалить все псевдонимы.</p>
<p>Если выполнить <code>alias</code> без параметров, она выведет список всех определенных псевдонимов, причем в виде команд, которыми они создаются.</p>
<p>Кстати, имя псевдонима вполне может совпадать с именем существующей команды. Более того, это часто используется для задания командам «параметров по умолчанию». Например, у меня есть такой псевдоним:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">ls</span></span>=<span style="color: #ff0000;">&quot;ls --color=auto&quot;</span></pre></div></div>

<p>Теперь «команда» <code>ls</code> будет раскрашивать свой вывод, и это не придется указывать явно. Если же мы хотим обратиться к исходной команде (то есть, временно запретить раскрытие псевдонимов), нужно перед ее именем поставить символ «\» (<code>\ls</code>).</p>
<h4>Повторение набранного</h4>
<p>Существуют специальные комбинации символов, хранящие последнюю введенную команду и ее аргументы:</p>
<ul>
<li><code>!!</code> — вся команда целиком;</li>
<li><code>!*</code> — все аргументы;</li>
<li><code>!:2</code> — второй аргумент;</li>
<li><code>!$</code> — последний аргумент.</li>
</ul>
<p>Чаще всего нужно обратиться или ко всей команде, или к последнему аргументу. Например, можно создать псевдоним на основе последней команды:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #007800;">foo</span>=<span style="color: #ff0000;">&quot;!!&quot;</span></pre></div></div>

<p>или повторно выполнить команду от имени root:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">!!</span></pre></div></div>

<p>или что-нибудь сделать с только что созданным файлом:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">touch</span> longscriptname.sh
<span style="color: #c20cb9; font-weight: bold;">chmod</span> +x <span style="color: #000000; font-weight: bold;">!</span>$</pre></div></div>

<p>В общем, вариантов много, проявите фантазию.</p>
<h4>Поиск по истории команд</h4>
<p>Это, наверное, и так все знают, но все же. Жмем Ctrl-r, вводим часть команды, затем жмем Ctrl-r до тех пор, пока не отобразится нужная команда. Enter.</p>
<p>На этот раз все. Призываю читателей поделиться своим bash-кунг-фу (по желанию добавлю в пост).</p>
<p><span style="color: #999999;">&#8212;&#8212;&#8212;&gt; Постовой</span></p>
<p>Теперь все знают, что crystalbit ведёт <a href="http://parsers.info">delphi блог</a> и обсуждает там аспекты программирования.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2010/01/time-saving-in-bash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visual Studio разрушает мозг</title>
		<link>http://typedef.ru/2010/01/visual-studio-rot-the-mind/</link>
		<comments>http://typedef.ru/2010/01/visual-studio-rot-the-mind/#comments</comments>
		<pubDate>Sun, 17 Jan 2010 05:23:20 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[продуктивность]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=510</guid>
		<description><![CDATA[Хе-хе, это не я, это все Петцольд сказал. Уж кому, как не ему, это знать!
А если честно, я с ним согласен. И сам все больше и больше отхожу от IDE в пользу Emacs, причем без средств управления проектами (да, я иногда меняю свое мнение). Во-первых, я нахожу, что «управление проектом» в техническом смысле — штука несколько эфемерная, [...]]]></description>
			<content:encoded><![CDATA[<p>Хе-хе, это не я, это все <a href="http://www.charlespetzold.com/etc/DoesVisualStudioRotTheMind.html" target="_blank">Петцольд сказал</a>. Уж кому, как не ему, это знать!</p>
<p>А если честно, я с ним согласен. И сам все больше и больше отхожу от IDE в пользу Emacs, причем <a href="http://typedef.ru/2009/05/eclipse-vs-emacs/" target="_blank">без средств управления проектами</a> (да, я иногда меняю свое мнение). Во-первых, я нахожу, что «управление проектом» в техническом смысле — штука несколько эфемерная, и, во-вторых, в Emacs оно сделано ужасно неудобно.</p>
<p>В результате я решил, что хороший текстовый редактор повышает мою производительность гораздо сильнее, чем хорошая IDE. А автоматизация сборки и тестирования вполне удовлетворяется Autotools или cmake (статьи про которые я все никак не допишу), а что не смогут они, смогут сценарии bash или Power Shell.</p>
<p>P.S. Ссылку на Петцольда стащил у <a href="http://thesz.livejournal.com/1049402.html" target="_blank">Сергея Зефирова</a>.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2010/01/visual-studio-rot-the-mind/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>cm-super и Fedora 12</title>
		<link>http://typedef.ru/2010/01/cm-super-fedora-12/</link>
		<comments>http://typedef.ru/2010/01/cm-super-fedora-12/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 10:55:00 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[LaTeX]]></category>
		<category><![CDATA[грабли]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=506</guid>
		<description><![CDATA[Почему-то в репозиториях Fedora 12 отсутствует замечательный пакет Type1-шрифтов cm-super. Так как жизни я себе без него не представляю, то пришлось брать соответствующий пакет на CTAN и ставить вручную. Суть поста в том, что идущие в комплекте с cm-super инструкции по установке неверны. Начиная с некоторого времени стандартные пути к .map- и .enc-файлам в TeX [...]]]></description>
			<content:encoded><![CDATA[<p>Почему-то в репозиториях Fedora 12 отсутствует замечательный пакет Type1-шрифтов <strong>cm-super</strong>. Так как жизни я себе без него <a href="http://typedef.ru/2009/09/microtype-fonts-problem/" target="_blank">не представляю</a>, то пришлось брать соответствующий <a href="http://www.ctan.org/tex-archive/fonts/ps-type1/cm-super/" target="_blank">пакет на CTAN</a> и ставить вручную. Суть поста в том, что <strong>идущие в комплекте с cm-super инструкции по установке неверны</strong>. Начиная с некоторого времени стандартные пути к .map- и .enc-файлам в TeX Live были изменены, о чем сказано в <a href="http://tug.org/texlive/mapenc.html" target="_blank">официальном предупреждении</a>.</p>
<p>Для лентяев добрые люди сочинили <a href="http://tex.raleigh.ru/doku.php/faq/cmsuper" target="_blank">установочный скрипт</a> (внизу страницы).</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2010/01/cm-super-fedora-12/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Emacs: переключаем раскладку одинаково с ОС</title>
		<link>http://typedef.ru/2010/01/emacs-switching-input-method-as-in-os/</link>
		<comments>http://typedef.ru/2010/01/emacs-switching-input-method-as-in-os/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 22:10:34 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[хитрости]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=500</guid>
		<description><![CDATA[Наверное, первое, что неприятно поражает новичка в Emacs — невозможность использовать системные средства для переключения языка ввода. Не в том смысле, что оно не работает. А в том, что переключение на любой отличный от английского язык средствами ОС превращает Emacs в Notepad. Перестают работать все клавиатурные комбинации! Паника!
К счастью, Emacs, как и всякая уважающая себя [...]]]></description>
			<content:encoded><![CDATA[<p>Наверное, первое, что неприятно поражает новичка в Emacs — невозможность использовать системные средства для переключения языка ввода. Не в том смысле, что оно не работает. А в том, что переключение на любой отличный от английского язык средствами ОС превращает Emacs в Notepad. Перестают работать все клавиатурные комбинации! Паника!</p>
<p>К счастью, Emacs, как и всякая уважающая себя ОС, имеет собственный механизм переключения языков, кодировок и прочего. И все это даже работает. Одна беда — нельзя повесить переключение и в системе, и в Emacs на одну и ту же клавишу, потому что система в таком случае тоже будет переключаться. А пользоваться разными сочетаниями в Emacs и вне него&#8230; Что ж, я долгое время так и поступал. Неудобно.</p>
<p>Итак, задача:</p>
<ol>
<li><strong>Хотим переключаться везде по одной и той же клавише.</strong> Причем, чтобы если мы нажимаем эту клавишу в Emacs, использовался его внутренний механизм, в остальных случаях пусть этим занимается ОС.</li>
<li><strong>Хотим, чтобы п. 1 работал и в Windows, и в Linux.</strong> И желательно чтобы сценарий загрузки был общим.</li>
</ol>
<p>Первый пункт, исходя из общечеловеческой логики, может быть разрешен двумя путями:</p>
<ul>
<li>убедить ОС не переключаться, пока активен Emacs;</li>
<li>после одновременного переключения и в ОС, и в Emacs, переключить ОС обратно.</li>
</ul>
<p>Оказывается, первый вариант реализуем в Linux, а второй в Windows. Дальнейшее изложение предполагает, что в качестве универсальной клавиши переключения выбран Caps Lock.</p>
<p>Для Linux палочкой-выручалочкой оказывается сочетание <a href="http://en.wikipedia.org/wiki/Smart_Common_Input_Method" target="_blank">SCIM</a>/<a href="http://code.google.com/p/ibus/" target="_blank">iBus</a> и xmodmap. С помощью xmodmap можно <a href="http://efod.se/writings/linuxbook/html/caps-lock-to-ctrl.html" target="_blank">переназначить Caps Lock</a> на какое-нибудь неиспользуемое действие, например, F13. Для этого в файл ~/.Xmodmap вписываем строку:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">keycode 66 = F13</pre></div></div>

<p>Число 66 — это код соответствующей клавиши. Скорее всего, у вас будет такой же, но лучше в этом убедиться с помощью утилиты xev.</p>
<p>Дальше убиваем системную переключалку раскладок (без особых зверств), и настраиваем SCIM/iBus на переключение по F13, а затем отключаем переключение для Emacs, вписывая в ~/.Xdefaults строку:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">Emacs*useXIM:false</pre></div></div>

<p>Теперь остается только подправить стартовый сценарий Emacs (.emacs или init.el), вставив туда:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>global-set-key <span style="color: #66cc66;">&#91;</span>f13<span style="color: #66cc66;">&#93;</span> 'toggle-input-method<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Выходим из сеанса, входим обратно, <span style="text-decoration: line-through;">тратим еще пару часов на доработку напильником,</span> и все заработает. Для Linux это все. Я намеренно опустил некоторые подробности про настройку SCIM/iBus, поскольку времена меняются, и старые инструкции становятся устаревшими. А тут я как бы не причем: «<em>настройте iBus на переключение по F13</em>» еще долго не устареет. В конце концов, гугл никто не отменял. Идея использовать SCIM и его аналоги не новая, об этом <a href="http://blog.agamestor.org/2009/02/emacs-scim.html" target="_blank">много где</a> можно прочитать.</p>
<p>В Windows такой фокус не пройдет, но зато один вдумчивый камрад предложил очень <a href="http://www.dima-exe.ru/2007/4/win32-emacs-and-change-language" target="_blank">изящное решение</a> (ссылка не работает?..), которое упомянуто выше: после переключения вернуть системную раскладку обратно. (Для установки Caps Lock в качестве клавиши переключения системной раскладкой нужно воспользоваться чем-то вроде <a href="http://haali.su/winutils/" target="_blank">lswitch</a> или <a href="http://teerapap.blogspot.com/2008/03/switch-input-language-by-caps-lock.html" target="_blank">лезть в реестр</a>.)</p>
<p>Теперь остается только вооружиться переменной system-type, и получим сценарий, который кроссплатформенно решает нашу задачу:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">eq</span> system-type 'windows-nt<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>defvar safe-language-change-flag <span style="color: #b1b100;">nil</span><span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> safe-language-change <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
       <span style="color: #66cc66;">&#40;</span>interactive<span style="color: #66cc66;">&#41;</span>
       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setq</span> safe-language-change-flag <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">not</span> safe-language-change-flag<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">when</span> safe-language-change-flag
         <span style="color: #66cc66;">&#40;</span>toggle-input-method<span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>w32-toggle-lock-key 'capslock<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
     <span style="color: #66cc66;">&#40;</span>global-set-key <span style="color: #66cc66;">&#40;</span>kbd <span style="color: #ff0000;">&quot;&lt;language-change&gt;&quot;</span><span style="color: #66cc66;">&#41;</span> 'safe-language-change<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>global-set-key <span style="color: #66cc66;">&#91;</span>f13<span style="color: #66cc66;">&#93;</span> 'toggle-input-method<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Правда, в случае запуска в натуральной консоли проблема все еще остается.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2010/01/emacs-switching-input-method-as-in-os/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Emacs как редактор по умолчанию в Windows</title>
		<link>http://typedef.ru/2010/01/emacs-as-default-windows-editor/</link>
		<comments>http://typedef.ru/2010/01/emacs-as-default-windows-editor/#comments</comments>
		<pubDate>Sun, 03 Jan 2010 20:47:34 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=493</guid>
		<description><![CDATA[С новым годом, кстати.
Настройка Emacs — это определенно то дело, которым стоит заниматься линуксоидам в Windows (после сборки чего-нибудь из исходников, разумеется). Замечательно успокаивает нервы и нормализует давление.
Что бы там ни говорили, а Emacs невыгодно отличается от своих аналогов долгим временем начальной загрузки, особенно если в процессе оной грузится пара десятков дополнительных модулей. Но если [...]]]></description>
			<content:encoded><![CDATA[<p>С новым годом, кстати.</p>
<p>Настройка Emacs — это определенно то дело, которым стоит заниматься линуксоидам в Windows (после <a href="http://typedef.ru/2009/12/qt-460-for-visual-studio-2008/" target="_blank">сборки чего-нибудь из исходников</a>, разумеется). Замечательно успокаивает нервы и нормализует давление.</p>
<p>Что бы там ни говорили, а Emacs невыгодно отличается от своих аналогов долгим временем начальной загрузки, особенно если в процессе оной грузится пара десятков дополнительных модулей. Но если для открытия файлов, скажем, <code>*.el</code>, назначить файл <code>runemacs.exe</code> редактором по умолчанию, то попытка открыть несколько файлов приведет к открытию равного количества экземпляров Emacs, со всеми вытекающими задержками и издержками. Мы же хотим, чтобы было как в Notepad++: редактор запускается один раз, и дальше все файлы открываются в нем.</p>
<p>Как сказал один емаксер, «учитесь любить Emacs Server». Учимся:</p>
<ol>
<li>типы файлов, которые хотим открывать Emacs&#8217;ом, ассоциируем с <code>%EMACSDIR%\bin\emacsclientw.exe</code>;</li>
<li>создаем переменную окружения <code>ALTERNATE_EDITOR="%EMACSDIR%\bin\runemacs.exe"</code>;</li>
<li>в начало файла <code>.emacs</code> (или <code>init.el</code>, у кого что) вставляем:<br />
<code># run emacs server<br />
(server-start)</code></li>
</ol>
<p>Теперь когда мы открываем файл, <code>emacsclientw </code>пытается найти запущенный Emacs-сервер. Если не находит, обращается к альтернативному редактору (<code>runemacs</code>), который открывает файл и запускает сервер. Если же сервер уже запущен, то файл просто открывается в новом буфере.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2010/01/emacs-as-default-windows-editor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Штрихкодовые координаты</title>
		<link>http://typedef.ru/2009/12/barcode-coordinates/</link>
		<comments>http://typedef.ru/2009/12/barcode-coordinates/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 08:53:59 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[идеи]]></category>
		<category><![CDATA[технологии]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=488</guid>
		<description><![CDATA[Почти во всех мобильниках есть камеры. Во многих есть встроенный GPS. Почему бы не кодировать географические координаты штрих-кодом?
Например, на информационных щитах для туристов можно размещать штрихкодированные координаты известных мест. Не знаете, как пройти к мавзолею? Сфотографируйте это:

Или, например, можно размещать такие координаты в рекламе или на визитках. Включаем воображение и видим светлое будущее. Осталось только:

договориться [...]]]></description>
			<content:encoded><![CDATA[<p>Почти во всех мобильниках есть камеры. Во многих есть встроенный GPS. Почему бы не <strong>кодировать географические координаты штрих-кодом</strong>?</p>
<p>Например, на информационных щитах для туристов можно размещать штрихкодированные координаты известных мест. Не знаете, как пройти к мавзолею? Сфотографируйте это:</p>
<p style="text-align: center;"><a title="Мавзолей штрихкод" rel="lightbox[pics488]" href="../wp-content/uploads/2009/12/barcode_mausoleum.png"><img class="aligncenter" src="../wp-content/uploads/2009/12/barcode_mausoleum.png" alt="Мавзолей штрихкод" width="506" height="158" /></a></p>
<p>Или, например, можно размещать такие координаты в рекламе или на визитках. Включаем воображение и видим светлое будущее. Осталось только:</p>
<ol>
<li>договориться о формате кодирования;</li>
<li>встроить простенькую распознавалку в программы GPS-навигации.</li>
</ol>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/12/barcode-coordinates/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Сборка Qt 4.6.0 для Visual Studio 2008</title>
		<link>http://typedef.ru/2009/12/qt-460-for-visual-studio-2008/</link>
		<comments>http://typedef.ru/2009/12/qt-460-for-visual-studio-2008/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 05:12:48 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Visual Studio]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=480</guid>
		<description><![CDATA[Установил я как-то Windows 7, и зело он мне приглянулся. Пожалуй, из всего, что я видел, здесь самый удобный интерфейс и самая высокая работоспособность «из коробки» (правда, я не пробовал еще MacOS и всякие маргинальные клавиатурно-ориентированные иксовые оболочки вроде xmonad). И GUI визуально шустрее, чем на моей Федоре. Так что на данный момент «господин назначил [...]]]></description>
			<content:encoded><![CDATA[<p>Установил я как-то Windows 7, и зело он мне приглянулся. Пожалуй, из всего, что я видел, здесь самый удобный интерфейс и самая высокая работоспособность «из коробки» (правда, я не пробовал еще MacOS и всякие маргинальные клавиатурно-ориентированные иксовые оболочки вроде xmonad). И GUI визуально шустрее, чем на моей Федоре. Так что на данный момент «<em>господин назначил Windows любимой осью</em>», и пингвинов загружает только по необходимости или нестерпимому зову сердца.</p>
<p>Чем занимается линуксоид, обретя свежую винду? Конечно же, собирает что-нибудь из исходников! Вот я и решил собрать себе последнюю Qt, да не просто собрать (этак можно MinGW прикрутить и спать спокойно), а так, чтобы почти вся разработка происходила в Visual Studio, и компилятор использовался местный, а не портированный. И чтоб отладка тоже из IDE.</p>
<p>Ну что ж, дело нехитрое:</p>
<ol>
<li><a href="http://qt.nokia.com/downloads" target="_blank">качаем Qt</a> и устанавливаем ее, скажем, в C:\qt\2009.05;</li>
<li>на всякий случай копируем в C:\qt\4.6;</li>
<li>устанавливаем переменные окружения:<br />
QTDIR=C:\Qt\4.6\qt;<br />
QMAKESPEC=win32-msvc2008;<br />
добавляем C:\Qt\4.6\qt\bin в Path;</li>
<li>дистрибутив версии 4.6 содержит забытые авторами временные файлы, которые приводят к ошибкам при сборке (настоящий opensource не собирается с первого раза, но зато всегда можно найти <a href="http://bugreports.qt.nokia.com/browse/QTBUG-6014" target="_blank">ответ на официальном сайте</a>), поэтому нужно удалить файлы:<br />
C:\Qt\4.6\qt\src\script\tmp\moc\debug_shared\mocinclude.tmp<br />
C:\Qt\4.6\qt\src\script\tmp\moc\release_shared\mocinclude.tmp<br />
C:\Qt\4.6\qt\src\3rdparty\webkit\WebCore\tmp\moc\debug_shared\mocinclude.tmp<br />
C:\Qt\4.6\qt\src\3rdparty\webkit\WebCore\tmp\moc\release_shared\mocinclude.tmp<br />
будем надеяться, что в следующих релизах эта ошибка будет исправлена;</li>
<li>запускаем Visual Studio, и из нее консоль (Tools → Visual Studio 2008 Command Prompt);</li>
<li>переходим в C:\Qt\4.6\qt;</li>
<li>запускаем configure, отвечаем на его вопросы; начнется подготовка к сборке, которая продлится минут 5-10;</li>
<li>запускаем nmake, начнется сборка, которая продлится несколько часов (есть смысл оставить на ночь); в ходе сборки будет куча предупреждений, но не стоит принимать это близко к сердцу, главное чтобы процесс сборки не завершился сообщением об ошибке;</li>
<li>закрываем Visual Studio, качаем и устанавливаем <a href="http://qt.nokia.com/downloads/visual-studio-add-in" target="_blank">add-in</a>;</li>
<li>запускаем Visual Studio, идем в Qt → Qt Options и указываем там версию вместе с путем к установленному Qt;</li>
<li>C:\Qt\2009.5 можно стирать;</li>
<li>все.</li>
</ol>
<p style="text-align: center;"><a title="Qt 4.6.0, Visual Studio 2008" rel="lightbox[pics480]" href="http://typedef.ru/wp-content/uploads/2009/12/qt46msvc2008.png"><img class="attachment wp-att-483 centered" src="http://typedef.ru/wp-content/uploads/2009/12/qt46msvc2008.png" alt="Qt 4.6.0, Visual Studio 2008" width="595" height="489" /></a></p>
<p>Незнание пункта 4 стоило мне нескольких часов потраченного напрасно времени, которое мои читатели теперь смогут потратить более продуктивно. Благодарности принимаются в произвольной форме.</p>
<p>Если ставить LGPL-версию Qt, то Qt Designer не будет интегрирован в VS, а запустится отдельно при открытии UI-файла. Это, конечно, неудобство, но не критичное.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/12/qt-460-for-visual-studio-2008/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Гугл-убийца</title>
		<link>http://typedef.ru/2009/12/killer-google/</link>
		<comments>http://typedef.ru/2009/12/killer-google/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 19:26:26 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[грабли]]></category>
		<category><![CDATA[жизнь]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=478</guid>
		<description><![CDATA[Гугл меня сегодня чуть не убил, натурально. У меня на главной странице виджет с погодой. Смотрю утром: +4º. Ну, думаю, опять синоптики облажались со своими морозами. Оделся соответственно погоде, по-осеннему. Приезжаю на работу — а Гугл показывает уже -18º. Тут-то я и понял, почему мне по дороге казалось, что как-то несколько прохладно для четырех градусов&#8230;
К [...]]]></description>
			<content:encoded><![CDATA[<p>Гугл меня сегодня чуть не убил, натурально. У меня на главной странице виджет с погодой. Смотрю утром: +4º. Ну, думаю, опять синоптики облажались со своими морозами. Оделся соответственно погоде, по-осеннему. Приезжаю на работу — а Гугл показывает уже -18º. Тут-то я и понял, почему мне по дороге казалось, что как-то несколько прохладно для четырех градусов&#8230;</p>
<p>К сожалению, скриншот сделать не смог.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/12/killer-google/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Уши в самолете и под водой</title>
		<link>http://typedef.ru/2009/12/ears-in-a-plane-and-underwater/</link>
		<comments>http://typedef.ru/2009/12/ears-in-a-plane-and-underwater/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 07:17:55 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[хитрости]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=474</guid>
		<description><![CDATA[Обсуждая c коллегами свой последний отпуск, с удивлением обнаружил, что многие до сих пор не знают, почему в самолете закладывает уши, и как с этим бороться. Уверен, что большинство читателей не нуждаются в моих советах, но мне будет достаточно, если этим постом я помогу хотя бы одному человеку.
Итак. Неприятные ощущения в ушах возникают из-за того, [...]]]></description>
			<content:encoded><![CDATA[<p>Обсуждая c коллегами свой последний отпуск, с удивлением обнаружил, что многие до сих пор не знают, <strong>почему в самолете закладывает уши, и как с этим бороться</strong>. Уверен, что большинство читателей не нуждаются в моих советах, но мне будет достаточно, если этим постом я помогу хотя бы одному человеку.</p>
<p>Итак. Неприятные ощущения в ушах возникают из-за того, что при наборе высоты давление в салоне самолета понижается вплоть до значения как на высоте примерно 3000 м над уровнем моря. При снижении, наоборот, давление постепенно понижают до нормального. Это делается не для того, чтобы пассажирам было не скучно, а чтобы конструкцию самолета излишне не нагружать большой разницей давлений внутри и снаружи.</p>
<p>Как известно, наша носоглотка соединена с ушами, но соединительный канал обычно закрыт. При этом образуется замкнутая полость, отгороженная от внешнего мира тонкой барабанной перепонкой. Когда давление в полости равно давлению снаружи, все нормально. Но <strong>как только снаружи давление снижается или повышается, наши перепонки начинают выгибаться, соответственно, наружу или вовнутрь</strong>. В принципе, давление на 3000 м не настолько низкое, чтобы причинить какой-то вред ушам, но его достаточно, чтобы испортить удовольствие от полета.</p>
<p>При появлении малейшего дискомфорта в ушах нужно выполнить любое из следующих действий:</p>
<ul>
<li>зевнуть (если умеете делать это произвольно);</li>
<li>выдвинуть вперед нижнюю челюсть и сглотнуть, можно при этом еще покачать головой из стороны в сторону;</li>
<li>зажать пальцами нос и попытаться через него выдохнуть (только аккуратно!).</li>
</ul>
<p>Все это шаманство призвано <strong>открыть канал между носоглоткой и ушами</strong>, тем самым уравняв давление с двух сторон от барабанной перепонки.</p>
<p>Примерно то же, но гораздо быстрее, происходит, когда мы ныряем под воду. Наверняка вы чувствовали это неприятное давление на уши, если ныряли с маской и ластами. Дайверам обычно приходится «продуваться» каждые 1-2 метра глубины, иначе можно остаться без ушей. Но даже не все дайверы знают, что не обязательно иметь баллон за спиной, чтобы уравнивать давление. Когда в следующий раз будете нырять в Черном море за крабами, попробуйте один из перечисленных выше способов, и вы удивитесь, насколько комфортнее будет под водой даже на глубине 2-3 м.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/12/ears-in-a-plane-and-underwater/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Почему я против open source</title>
		<link>http://typedef.ru/2009/11/why-i-am-against-open-source/</link>
		<comments>http://typedef.ru/2009/11/why-i-am-against-open-source/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 09:20:48 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[история]]></category>
		<category><![CDATA[открытое ПО]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=467</guid>
		<description><![CDATA[Я не зря написал «open source» с маленькой буквы, потому что сегодня в фокусе моего внимания не одноименное сообщество, а сама тенденция роста количества софта, который раздают бесплатно и/или с открытыми исходниками. Скажу даже больше: я против не только открытого софта, а вообще бесплатного.
Истоки такого альтруизма программистов можно обнаружить в культуре хакеров, начавшейся аж в [...]]]></description>
			<content:encoded><![CDATA[<p>Я не зря написал «open source» с маленькой буквы, потому что сегодня в фокусе моего внимания не одноименное сообщество, а сама тенденция роста количества софта, который раздают бесплатно и/или с открытыми исходниками. Скажу даже больше: я против не только открытого софта, а вообще бесплатного.</p>
<p>Истоки такого альтруизма программистов можно обнаружить в культуре хакеров, начавшейся аж в 60-х годах. Об этом можно почитать в замечательной книге Стивена Леви «<a href="http://lib.aldebaran.ru/author/levi_stiven/levi_stiven_hakery_geroi_kompyuternoi_revolyucii/" target="_blank">Хакеры</a>». В то время свободное ПО было практически единственным вариантом: рынка софта как такового не было — был рынок железа. Общей аппаратной архитектуры не было, цены были фантастически высокими, и компьютеры являлись штучным товаром, к которому <strong>софт поставлялся в виде бесплатного дополнения</strong>.</p>
<p>Казалось бы, <strong>раз программы кто-то пишет, то он должен получать за это соответствующее вознаграждение</strong>. Но откуда взять вознаграждение, если софт раздается бесплатно? Выходит, программисты не создают добавочной стоимости? Однако в то время такая модель распространения была естественной и протестов не вызывала по двум причинам:</p>
<ol>
<li>Программисты таки создавали добавочную стоимость, но эта стоимость относилась к железу, так как компьютеры продавались вместе с набором программ. <strong>Чем лучше программы для компьютера, тем дороже его можно продать</strong>. Ну, а поскольку стандартной архитектуры не было, то открытие исходников не имело негативных последствий: все, кто мог ими воспользоваться, сначала должны были купить компьютер, с которым этот софт и так шел в комплекте.</li>
<li>В то время каждый пользователь был программистом, поэтому <strong>открытый софт был просто частью натурального обмена</strong>. Сегодня я отдал свою программу Васе, а завтра он отдаст мне свою.</li>
</ol>
<p>Но жизнь-то — штука изменчивая, и вот, подвинув бородатых хакеров, за терминалы уселись банковские служащие и бухгалтеры. Потом все нарастающая стандартизация аппаратуры, платформенная независимость языков программирования, и вдруг — хоп! Программисты остались в меньшинстве, железо стало дешевым, а одну и ту же программу можно, хвала Юниксам, если не запустить, то уж собрать почти на любой платформе. Собственно, <strong>исчезли основные предпосылки существования опенсорса</strong>, имевшие место в 60-е и 70-е.</p>
<p>Но что же такое происходит? Open source мало того что не загнулся, так еще и продолжил развиваться. Сегодня уже непросто найти такую коммерческую программу, для которой бы не было аналогов с открытыми исходниками. Какие же причины побуждают программистов в наше время этим заниматься?</p>
<ol>
<li><strong>Интерес</strong>. Людям просто нравится творить. Но так как большинство программистов — не бизнесмены, и не способны продать свои творения, они их просто раздают. Впрочем, есть и идейные, которые раздают из принципиальных соображений.</li>
<li><strong>Известность</strong>. Open source очень демократичен. Напиши хорошую программу, которой будут пользоваться миллионы, — и интерес к тебе со стороны работодателей сразу повысится. Собственные разработки с открытыми исходниками служат отличной заменой традиционным резюме: просмотрев исходники программы и историю ее разработки, можно гораздо больше узнать о разработчике, чем в ходе получасового собеседования.</li>
<li><strong>Работодатель за это платит</strong>.</li>
</ol>
<p>Если с первыми двумя пунктами все понятно, то третий не очень прозрачен. Приведенный ранее механизм с повышением стоимости железа за счет софта уже не работает. Тогда откуда же прибыль, чтобы платить программистам? Есть несколько вариантов:</p>
<ol>
<li>Код с открытыми исходниками не является самодостаточной программой, а представляет собой некую библиотеку или фреймворк, являющиеся <strong>побочным продуктом при разработке чего-то большего</strong>. Исходники открываются, как правило, из рекламных соображений. Прибыль косвенная.</li>
<li>Компания активно <strong>использует свой же продукт с открытыми исходниками в своих разработках</strong>. Очевидно, что основная прибыль получается другими путями, а открытие исходников — просто жест доброй воли или, опять-таки, реклама. Прибыль снова косвенная.</li>
<li>Мифическая «<strong>техподдержка</strong>», о которой будет твердить не слишком подкованный апологет open source, объясняя, откуда у опенсорсников деньги берутся. Этот путь получения дохода имеет смысл разве что <strong>для крупных компаний</strong> вроде Rad Hat или Microsoft, которые могут поставлять настолько большие и сложные продукты, что для них может потребоваться обучение специалистов и поддержка (платные, разумеется).</li>
<li><strong>Open source, вообще говоря, ничуть не противоречит коммерческому софту</strong>. Поэтому можно путем хитрого лицензирования требовать с клиентов денег, если продукт с открытыми исходниками используется в коммерческих разработках (вспомним Qt как хрестоматийный пример).</li>
<li><strong>Научные гранты</strong>.</li>
<li>Всякие маргинальные способы вроде<strong> пожертвований или встраивания рекламы</strong> в пользовательский интерфейс (фуу).</li>
</ol>
<p>То есть, прибыль получить можно, если хорошо постараться. А открытие исходников дает, во-первых, армию бесплатных энтузиастов-тестеров, а во-вторых, на пустом месте возникает лишнее конкурентное преимущество: <strong>при прочих равных условиях софт с открытыми исходниками (не говоря уж о бесплатном) предпочтительнее</strong>, просто потому что. Наверняка 99% пользователей в исходники не полезут, зато их будет греть мысль, что такая возможность у них есть.</p>
<p>Программистов, которые могут себе позволить и хотят заниматься разработкой открытого софта, подавляющее меньшинство. <strong>Качественный открытый софт убивает конкуренцию</strong> (и, в некотором смысле, прогресс) среди закрытого коммерческого софта. То есть, если разработана некоторая открытая программа, то вероятность появления успешной аналогичной (или даже чуть более функциональной) закрытой коммерческой программы исчезающе мала (пример — браузеры). Да и открытой, в общем-то, тоже. Выходит, что open source замедляет прогресс!</p>
<p>Я считаю, что <strong>этично будет продолжать развитие открытого софта (и открытой информации) в среде разработчиков и ученых</strong>, так как там это будет проявлением натурального обмена — там отношения не производитель-потребитель, а скорее производитель-производитель. Вот смотрите:</p>
<ol>
<li>Я написал научную статью и выложил ее в открытый доступ. Это ускоряет развитие науки, так как другие ученые могут опираться на мои результаты.</li>
<li>Я написал библиотеку нечеткой логики и открыл ее исходники. Это ускоряет прогресс программирования, так как остальные разработчики могут сэкономить свое время, если им понадобятся такие функции. Если им нужно внести какие-то изменения, они берут и вносят. Здесь важно, чтобы лицензия открытого кода позволяла любое его использование, в том числе коммерческое.</li>
<li>Я написал редактор UML-диаграмм и раздаю его бесплатно. Это помогает другим разработчикам в их работе. Конечно, это убивает конкуренцию среди платных редакторов UML, но в целом служит прогрессу программирования.</li>
<li>У меня бессонница, поэтому я год ночами писал программу управления личными финансами, а так как мне лень заниматься продажами, то я раздаю эту программу бесплатно. Если программа удобная, то платные уже покупать никто не будет, даже если они немножко лучше. Конкуренцию теперь может составить только более функциональная бесплатная программа.</li>
</ol>
<p>Итак, <strong>моя позиция по поводу всего вышеобозначенного</strong>:</p>
<ul>
<li>информация должна быть открытой;</li>
<li>средства разработки и научные инструменты должны быть бесплатны и, возможно, открыты;</li>
<li>остальные программы не должны быть бесплатными (но могут быть открытыми);</li>
<li>тем не менее, если уже есть хороший открытый/бесплатный софт, то глупо было бы им не пользоваться.</li>
</ul>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/11/why-i-am-against-open-source/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Книжная халява</title>
		<link>http://typedef.ru/2009/11/knizhnaya-xalyava/</link>
		<comments>http://typedef.ru/2009/11/knizhnaya-xalyava/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 07:55:05 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[книги]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=463</guid>
		<description><![CDATA[Сегодня по дороге на работу купил «Порождающее программирование» и «Распределенные системы». За 40 рублей каждую. А неделей раньше там же приобрел «C++ Boost Graph Library» по той же цене.
Простите за кощунство, но такая цена на книги выгодна даже если их не читать, а использовать каким-нибудь другим местом.
Где купил — не скажу :)
]]></description>
			<content:encoded><![CDATA[<p>Сегодня по дороге на работу купил «<a href="http://www.ozon.ru/context/detail/id/2896278/" target="_blank">Порождающее программирование</a>» и «<a href="http://www.ozon.ru/context/detail/id/1431767/" target="_blank">Распределенные системы</a>». <strong>За 40 рублей каждую.</strong> А неделей раньше там же приобрел «<a href="http://www.ozon.ru/context/detail/id/2457394/" target="_blank">C++ Boost Graph Library</a>» по той же цене.</p>
<p>Простите за кощунство, но такая цена на книги выгодна даже если их не читать, а использовать каким-нибудь другим местом.</p>
<p>Где купил — не скажу :)</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/11/knizhnaya-xalyava/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CiteULike и асфальтовый каток</title>
		<link>http://typedef.ru/2009/10/citeulike-and-a-road-roller/</link>
		<comments>http://typedef.ru/2009/10/citeulike-and-a-road-roller/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 21:40:33 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[грабли]]></category>
		<category><![CDATA[инструменты]]></category>
		<category><![CDATA[наука]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=457</guid>
		<description><![CDATA[Наверное, искусственному разуму в недрах CiteULike не понравились мои легкомысленные высказывания в его адрес, и он решил мстить&#8230; Или просто у разработчиков  руки смонтированы в неправильное место? Сейчас разберемся.
Сначала я загрузил туда книгу: создал запись, ввел библиографическую информацию, а потом и залил к ним на сервер PDFку. Не прошло и получаса, как запись об [...]]]></description>
			<content:encoded><![CDATA[<p>Наверное, искусственному разуму в недрах CiteULike не понравились мои <a href="http://typedef.ru/2009/10/personal-online-scientific-library/" target="_blank">легкомысленные высказывания</a> в его адрес, и он решил мстить&#8230; Или просто у разработчиков  руки смонтированы в неправильное место? Сейчас разберемся.</p>
<p>Сначала я загрузил туда книгу: создал запись, ввел библиографическую информацию, а потом и залил к ним на сервер PDFку. Не прошло и получаса, как запись об этой книге исчезла из моей тамошней личной библиотеки, как будто ее и не было. Первое подозрение у меня было на <em>копирастов</em>: небось, углядели в PDF-файле нарушение авторских прав, и стерли без суда и следствия.</p>
<p>Я так просто не сдался и продолжил эксперимент. Пошел на <a href="http://citeseerx.ist.psu.edu/" target="_blank">CiteSeerX</a> и нашел там общедоступную статью, которую и залил на CiteULike (кстати, шикарнейшая фича — автоматический экспорт библиографических данных с CiteSeerX и других подобных сайтов). Теперь у копирастов не было повода. Но через час статья все равно исчезла.</p>
<p>Было особенно обидно, что исчезновение не сопровождалось никакими спецэффектами вроде клубов дыма, воя сирен или хотя бы надписи в профиле «статья такая-то удалена». Я согласен даже на отсутствие объяснения причин (это позволяет предположить, что я чего-то недопонял), но какое-то уведомление должно быть! Нет, раздел «Library» нагло врет: «<em>You haven&#8217;t added any articles to your library yet</em>».</p>
<p>Еще одна статья, закинутая в порыве последней надежды, сумела пережить ночь, после чего отправилась вслед за своими почившими товарищами. Черная дыра прям, даже заходить теперь туда страшно. Вдруг и меня засосет? И не останется от меня ничего, только надпись у жены в паспорте: «<em>You haven&#8217;t married any man yet</em>». Стивен Кинг отдыхает.</p>
<p>Теперь серьезно. CiteULike совершил вопиющее, непростительное преступление. <strong>Я потратил время на ввод данных, а мои данные были целенаправленно удалены.</strong> Неуважение ко времени пользователя — это смертный грех для любого софта. Заблокируйте данные, запретите скачивание, но <strong>удалять созданное пользователем без его согласия — нельзя</strong>.</p>
<p>Другое преступление, не менее тяжелое, — <strong>молчание в экстренной ситуации</strong>. Большая удача, что стерлись первые же добавленные статьи. А что если бы я туда напихал 400 статей, а потом некоторые из них взяли бы и исчезли? <strong>Я мог не заметить потери важной информации</strong>. Замалчивание таких случаев исключает возможность доверия. Подвел сейчас — значит, может подвести и потом.</p>
<p>Нет, я не буду писать разработчикам. К ним применима та же логика. Придется все же браться за дело самому.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/10/citeulike-and-a-road-roller/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Личная научная библиотека онлайн</title>
		<link>http://typedef.ru/2009/10/personal-online-scientific-library/</link>
		<comments>http://typedef.ru/2009/10/personal-online-scientific-library/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 09:21:45 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[инструменты]]></category>
		<category><![CDATA[наука]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=452</guid>
		<description><![CDATA[Я довольно продолжительное время носился с идеей написать  программу для управления личной библиотекой научных источников (книг, статей, отчетов и т.д.). Мои потребности были нехитрыми, но одних средств файловой системы явно не хватало.
С одной стороны, в иерархической структуре вроде дерева каталогов расположить все мои источники просто невозможно. Например, гипотетическая статья о моделировании протокола TCP относится сразу [...]]]></description>
			<content:encoded><![CDATA[<p>Я довольно продолжительное время носился с идеей написать  программу для управления личной библиотекой научных источников (книг, статей, отчетов и т.д.). Мои потребности были нехитрыми, но одних средств файловой системы явно не хватало.</p>
<p>С одной стороны, в иерархической структуре вроде дерева каталогов расположить все мои источники просто невозможно. Например, гипотетическая статья о моделировании протокола TCP относится сразу к нескольким категориям, скажем, «моделирование» и «TCP». Это теговый подход, и возможность хранить такие пометки и осуществлять по ним поиск уже была бы большим подспорьем. Еще лучше, чтобы система категорий/тегов была иерархической, чтобы можно было пометить статью тегами «<em>моделирование%имитационное моделирование</em>» и «<em>передача данных%сетевые протоколы%стек TCP/IP%TCP</em>». В принципе, это реализуемо с помощью ссылок, но, во-первых, это муторно, а во-вторых, у ссылок предостаточно ограничений. В будущем этим должны будут заниматься теговые ФС, но сейчас этот вариант не подходит.</p>
<p>С другой стороны, помимо семантических меток, прикрепленных к источнику, хотелось бы еще хранить и некоторую дополнительную информацию:</p>
<ul>
<li>статус (прочитано/срочно прочитать/просмотреть и забыть);</li>
<li>библиографические данные, желательно с возможностью автоматического экспорта в BibTeX;</li>
<li>любая другая присоединенная информация, например, конспект, ссылка на сайт издательства или просто какие-то заметки.</li>
</ul>
<p>К счастью, я не успел начать писать свою программу, когда нашел <a href="http://www.citeulike.org/" target="_blank">CiteULike</a>. Это ровно то, о чем я говорил. Даже не буду вдаваться в подробности и описывать фичи. Большая часть из них мне не нужна, а остальное я уже описал выше. Позволю себе только пару оговорок:</p>
<ul>
<li>теги таки не иерархические;</li>
<li>при экспорте в BibTeX добавляются мусорные поля вроде citeulike-article-id и priority, которые, впрочем, несложно вычистить;</li>
<li>много всякой лишней ерунды, загромождающей интерфейс (явно не обошлось без <em>feature creature</em>);</li>
<li>существующую локальную библиотеку статей переносить туда придется долго и с трудом; настольная программа могла бы большую часть работы сделать самостоятельно, пройдя по иерархии каталогов и <a href="http://mydebianblog.blogspot.com/2009/09/linux.html" target="_blank">индексируя файлы</a>.</li>
</ul>
<p>В целом штуковина полезная, но не без недостатков. Будет у меня свободное время — напишу свою правильную версию, с блэкджеком и прочей атрибутикой.</p>
<p>UPD: прежде чем пользоваться CiteULike, ознакомьтесь со <a href="http://typedef.ru/2009/10/citeulike-and-a-road-roller/">следующим постом</a>. Редакция изменила свое мнение.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/10/personal-online-scientific-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows, Linux или что там еще?</title>
		<link>http://typedef.ru/2009/10/windows-or-linux-or-something-else/</link>
		<comments>http://typedef.ru/2009/10/windows-or-linux-or-something-else/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 16:04:22 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=446</guid>
		<description><![CDATA[Везде есть свои плюхи и минухи. Ну вот, например.
С точки зрения пользователя:

Windows неэффективен и негибок (хотя многие об этом не подозревают);
Linux сложен в настройке и нестабилен (хотя многие это отрицают).

С точки зрения разработчика:

Windows сложен в изучении и неизящен; тысячи функций, не объединенных стройной идеологией; закрытые исходники не позволяют понять, как оно внутри работает;
Linux слишком разнообразен [...]]]></description>
			<content:encoded><![CDATA[<p>Везде есть свои <em>плюхи и минухи</em>. Ну вот, например.</p>
<p>С точки зрения пользователя:</p>
<ul>
<li>Windows неэффективен и негибок (хотя многие об этом не подозревают);</li>
<li>Linux сложен в настройке и нестабилен (хотя многие это отрицают).</li>
</ul>
<p>С точки зрения разработчика:</p>
<ul>
<li>Windows сложен в изучении и неизящен; тысячи функций, не объединенных стройной идеологией; закрытые исходники не позволяют понять, как оно внутри работает;</li>
<li>Linux слишком разнообразен и многолик; для написания реального софта приходится пользоваться множеством библиотек с невнятной документацией и не всегда корректной реализацией; да еще и вечная проблема совместимости дистрибутивов.</li>
</ul>
<p>Можно найти сотни доводов «против» и столько же «за». Те, кто устраивает по этому поводу священные войны, или обладают излишком времени, или просто глупы. Кто читает священные войны в поисках истины — делают это напрасно: в таких спорах <strong>умение убеждать работает гораздо сильнее компетенции</strong>.</p>
<p>Вот что нужно принимать во внимание при выборе:</p>
<ul>
<li>сложность установки, совместимость с железом;</li>
<li>сложность настройки;</li>
<li>наличие доступной информации по настройке и использованию ОС;</li>
<li>выбор нужного вам прикладного софта, его качество и цена;</li>
<li>стабильность и надежность;</li>
<li>ваша продуктивность при работе с ОС;</li>
<li>удовольствие от работы;</li>
<li>мощность, простота и стоимость средств разработки;</li>
<li>цена самой ОС и ее поддержки;</li>
<li>тенденции развития;</li>
<li>ценность знания этой ОС на рынке труда;</li>
<li>и так далее.</li>
</ul>
<p>Только это имеет значение, а не мнения других людей. Но некоторые вышеобозначенные критерии для разных людей сработают в разные стороны. Если, скажем, цена ОС является объективным показателем, то удовольствие от работы или даже сложность настройки — вещи субъективные. Кому-то нравится тыкать мышкой по кнопочкам, а кто-то ловит нереальный кайф от редактирования текстовых конфигов в черной, как наша жизнь, консоли. А кому-то просто нравятся надкушенные яблоки.</p>
<p>Беда в том, что разработчики ОС пытаются сделать так, чтобы <em>все</em> критерии для <em>всех</em> людей срабатывали в одну сторону. Это большая ошибка. Всем угодить невозможно, зато можно растерять нынешних последователей.</p>
<p>Например, я считаю неправильным курс Linux на доступность для «домохозяек». У него была своя замечательная ниша: ОС для бородатых гиков, да и еще неплохо подходил для серверных приложений. Были толпы высококвалифицированных фанатов. Теперь же эти толпы фанатов решили навязать свое мнение всему миру. В результате ядро распухло и мешает при ходьбе. Реинкарнация DLL Hell. Квалификация фанатов упала. Появилась куча клонов Windows-приложений, которые работают <em>чуть-чуть не так, как надо</em>. Зато опенсорс, да.</p>
<p>С Windows тоже беда, но обратная. Microsoft случайно сделал идеальную ОС для обычных пользователей: Windows XP.  Дальнейшие дерганья только подтверждают неизбежное: <a href="http://typedef.ru/2009/09/why-not-worth-learning-programmin/" target="_blank">все уже написано</a>. Пользователи хотят чего-то нового, но новое от Microsoft подозрительно напоминает старое. Чем успешно пользуется Apple, который принципиально ничего нового не делает, но зато делает <em>не так, как Microsoft</em>, чем и привлекает уставших от пятнадцати лет унылого интерфейса пользователей. Зато уж средства разработки Microsoft как блины печет: уже вон .NET 4 выходит. Несчастные разработчики в мыле корпят днями и ночами над книгами и мануалами, чтобы потом, прочитав последнюю страницу, обнаружить, что за это время вышло еще два фреймворка и три языка, и что они теперь мейнстрим. Утрирую, конечно, но скорость превращения версий дотнетов в legacy многих пугает (и я среди них).</p>
<p>Короче, смотрите на свои потребности и думайте головой. Идеальной ОС нет. Linux ужасный. Windows отвратительный. MacOS дурацкий.</p>
<p>P.S. Вообще-то я хотел ограничиться только предыдущим абзацем, но внезапный приступ графоманства заставил написать развернутое вступление.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/10/windows-or-linux-or-something-else/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>OpenOffice Impress во всей красе</title>
		<link>http://typedef.ru/2009/10/openoffice-impress-at-its-best/</link>
		<comments>http://typedef.ru/2009/10/openoffice-impress-at-its-best/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 07:57:25 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[грабли]]></category>
		<category><![CDATA[открытое ПО]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=439</guid>
		<description><![CDATA[Вчера весь день работал над своей SITOPовской презентацией в OO Impress 3.1.1 под Fedora 11. Работал — и получал от этого реальное удовольствие, настолько удобная программа. И что особенно приятно, думал я, не тормозит, радость моя, даже на моем стареньком рабочем P4. Ну просто счастье.
Сегодня прихожу на работу, открываю ту же презентацию, и&#8230; Иду пить [...]]]></description>
			<content:encoded><![CDATA[<p>Вчера весь день работал над своей SITOPовской презентацией в OO Impress 3.1.1 под Fedora 11. Работал — и получал от этого реальное удовольствие, настолько удобная программа. И что особенно приятно, думал я, не тормозит, радость моя, даже на моем стареньком рабочем P4. Ну просто счастье.</p>
<p>Сегодня прихожу на работу, открываю ту же презентацию, и&#8230; Иду пить чай. Отклика от интерфейса нет вообще. Смотрю в <code>top</code> — за звание самого прожорливого процесса борются <code>simpress.bin</code> и <code>convert</code>. Последний, очевидно, что-то делал со встроенными в презентацию картинками в формате EPS. Наверное, преобразовывал в какой-то свой внутренний формат. Ладно, минуты 4 попреобразовывал и перестал.</p>
<p>Но вот процесс <code>simpress.bin</code> после этого решил, что он теперь тут главный и ему все можно. Минут через пять интерфейс, наконец, начал неторопливо отвечать на мои действия. Все это время загрузка процессора одним этим процессом держалась на уровне 95%. Еще минут через пять тормоза почти окончательно пропали. Но стоит только просто поелозить колесиком мышки, как Impress тут же начинает жрать 20–40%. И основательно тормозит при любом редактировании. Xorg тоже хорош — глядя на Impress, выдает до 40% при прокрутке слайдов. Они что думают, я их за ушком чешу?.. Откуда такая гипервозбудимость?</p>
<p>Нет, правда, может кто-то знает? Уж очень не хочется для подготовки презентаций загружать винду.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/10/openoffice-impress-at-its-best/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Как преодолеть творческий кризис</title>
		<link>http://typedef.ru/2009/10/howto-overcome-creative-crysis/</link>
		<comments>http://typedef.ru/2009/10/howto-overcome-creative-crysis/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 17:34:24 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[продуктивность]]></category>
		<category><![CDATA[работа]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=410</guid>
		<description><![CDATA[Если кто-то из вас, коллеги, станет утверждать, что никогда не встречался с подобным кризисом, я ни за что не поверю. Такое бывает у всех, даже у суперзвезд творческих профессий. Бывает, что просто приходишь на работу и понимаешь, что ничего сегодня не получится. Внутренний голос прямо так и говорит: «Сегодня — не твой день. Смирись и [...]]]></description>
			<content:encoded><![CDATA[<p>Если кто-то из вас, коллеги, станет утверждать, что никогда не встречался с подобным кризисом, я ни за что не поверю. Такое бывает у всех, даже у суперзвезд творческих профессий. Бывает, что просто приходишь на работу и понимаешь, что ничего сегодня не получится. Внутренний голос прямо так и говорит: «Сегодня — не твой день. Смирись и попробуй завтра». На следующий день приходишь — и правда, работа спорится.</p>
<p>Почему такое с нами происходит, понять бывает непросто. Ваш семейный доктор Сан Саныч на основе богатого собственного опыта в данном вопросе выделил несколько категорий источников творческого кризиса:</p>
<ol>
<li><strong>личные психологические</strong>: поругался с собакой, увидел результаты выборов, вспомнил про кредит за квартиру;</li>
<li><strong>физические</strong>: хочется есть, не выспался, текут сопли, оторваны конечности;</li>
<li><strong>связанные с условиями работы</strong>: начальник идиот, зарплата маленькая, коллеги весь день отвлекают, сверхурочная работа;</li>
<li><strong>связанные с самой работой</strong>: работа слишком простая или слишком сложная, закончен один проект и надо начинать другой, начальство навязывает пути решения, ваще неинтересная работа, нет идей;</li>
<li><strong>ни с чем не связанные</strong>: просто тупо не хочется ничего делать.</li>
</ol>
<p>Составляя этот список, я немного сжульничал. Поэтому, пользуясь подходом доктора Х., сразу должен заявить, что если ваш кризис подходит под пункт 5, то вы врете. Не бывает беспричинных кризисов. Состояние «просто не хочется работать» говорит о том, что вы просто боитесь копаться в себе достаточно глубоко, чтобы выяснить истинную причину.</p>
<p><strong>Наше желание работать — сумма мотивирующих и демотивирующих воздействий</strong>. Воздействия эти бывают различной силы. Например, наличие большого интереса к текущей работе легко может перевесить недостаток сна или чувство голода. И напротив, разговаривающий весь день  по телефону коллега может надежно отбить желание работать, особенно если работа не слишком интересная. Еще есть всякие забавные факторы вроде «надо» и «зарплата», которые могут быть и положительными, и отрицательными. Конечно, такая модель слишком грубая, но качественно верная.</p>
<p>Терапия, таким образом, заключается в следующем:</p>
<ol>
<li>уменьшить количество и силу демотивирующих воздействий;</li>
<li>увеличить количество и силу мотивирующих воздействий.</li>
</ol>
<p>Никакой rocket science, как нетрудно видеть. Теперь перейдем к конкретным рецептам.</p>
<p>Если у вас личные психологические причины, то искренне сочувствую. «Тяжелые думы» норовят постоянно занимать мыслительные ресурсы, да и настроение снижают.  Мощный демотиватор. Однако если <strong>насильно погрузить себя на некоторое время в работу и пресекать попытки отвлекаться</strong>, то обычно через некоторое время весь негатив уходит: ему просто не хватает места в голове.</p>
<p>Физические причины нужно просто устранить. Тут и говорить не о чем.</p>
<p>Большинство, связанных с недовольством обстановкой на работе или самой работой, в большинстве случаев решаются прямым указанием на это начальству. Согласно общечеловеческой логике, <strong>начальник заинтересован в том, чтобы его сотрудники хорошо работали</strong>. Поэтому если вы не раздолбай по жизни, то ваши просьбы скорее всего будут удовлетворены. Исключения из этого правила только три:</p>
<ol>
<li>начальник идиот;</li>
<li>начальник вас понимает, но не в силах помочь (денег нет, директор не разрешает);</li>
<li>вы занимаетесь не той работой, которой хотели бы заниматься.</li>
</ol>
<p>В первых двух случаях неплохо бы рекурсивно обратиться к вышестоящему начальству. Но бывает так, что верхние боссы недоступны аки небожители, или им все по барабану, или вы уже дошли до самого верха и не нашли понимания. В таком случае лучше покинуть корабль в числе первых, пока еще все не развалилось. Третий случай означает, что у вас не творческий кризис, а просто кризис. Найдите себе мотиватор посильнее (например, деньги), смените работу или смиритесь.</p>
<p>Наконец, творческий кризис может быть вызван отсутствием идей. Здесь медицина бессильна, каждый ищет свой путь.</p>
<p><strong>Самое главное при малейших признаках кризиса — ни в коем случае ему не покоряться</strong>. Покорение — сильный демотивирующий фактор. Практика <em>«ладно, пойду на башорг, развеюсь, глядишь и настроение работать появится»</em> не работает.  Стоит только на минутку поддаться деструктивным настроениям, и все, день потерян, и хорошо если только день. Так и будете заниматься всякой ерундой, пока в сумму факторов не влезет совесть и всех не раскидает. У меня бывало такое, что творческий кризис длился до двух недель. Ужасное чувство.</p>
<p>На этот счет у меня есть свои правила. Они <strong>не устраняют причины кризиса</strong>, но здорово <strong>помогают, когда баланс факторов находится в районе нуля</strong>, и я вот-вот готов начать отлынивать.</p>
<ul>
<li>При малейших признаках состояния «влом работать» немедленно <strong>сменить занятие</strong> на другое, но имеющее отношение к работе — <strong>мозг должен продолжать находиться в рабочем режиме</strong>. Я обычно в таком случае начинаю читать какую-нибудь книжку по программированию. Через некоторое время надо попробовать вернуться к исходной деятельности.</li>
<li>Интерес к работе можно подогреть искусственно. Например, сообщить начальнику, что вечером сдашь работу, на которую планировалась неделя. Или начать обсуждать рабочие вопросы с коллегами. Иными словами, своими силами <strong>создать окружение, которое потом начинает само тебя подталкивать</strong>.</li>
<li>Если череда бессмысленных занятий таки сумела затянуть, нужно, как только это осознаешь, сразу же <strong>покинуть рабочее место</strong>. Походить по коридору, посмотреть в окно. В процессе этого выбрать следующее рабочее действие, после чего тигром броситься на свое место и начать выполнять задуманное. Мозг, пребывая в шоке от таких стремительных событий, соглашается работать.</li>
<li><strong>Убрать с рабочего места все, на что не относится к текущей работе</strong>. Просто диву даешься, насколько незначительные на первый взгляд вещи могут пожирать внимание и время. Например, у меня на столе лежала книга задней обложкой вверх; там была напечатана ее аннотация. Однажды я осознал, что <em>помню эту аннотацию наизусть</em>. Стал за собой следить и выяснил, что непроизвольно, в задумчивости, читаю ее несколько раз в день, причем после каждого прочтения взгляд соскальзывает в сторону, на другие книжки, потом на разбросанные статьи, потом на рукописные записи, а потом уже начинают всплывать какие-то воспоминания, обрывки старых идей&#8230; Если при этом я еще и не слишком хочу работать, то затягивает надолго.</li>
<li><strong>Заниматься посторонними делами  нужно на мотивационном максимуме</strong>. Например, вам пришла в голову замечательная идея, и сразу зачесались руки ее воплотить. Вот это то самое время, когда можно пообедать, выпить чаю, сходить в туалет и т.д. Во-первых, в это время можно более тщательно обдумать идею. Во-вторых, вы вернетесь к работе с подъемом и желанием свернуть горы. Малозаметное, но важное следствие: <strong>не стоит стремиться доделать работу к концу дня</strong>. Лучше оставить небольшую и несложную часть на завтра, чтобы с утра недоделанная работа послужила «трамплином» для вхождения в поток.</li>
<li><strong>Стараться не составлять распорядок дня</strong>, как бы это парадоксально ни звучало. Назначенные на определенное время события (обед в 13:00, чай в 17:00, уход с работы в 19:00) создают перед собой <em>кризисные зоны</em> размером до полутора часов. Скажем, вы заканчиваете некоторый этап работы за 5 минут до обеда. Будете ли вы начинать следующий этап? Скорее всего, нет. А если закончите за 10 минут? За полчаса? Думаю, идея понятна.</li>
</ul>
<p>Каждый легко может придумать еще кучу подобных правил для повышения собственной продуктивности, тем более что факторы у каждого свои.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/10/howto-overcome-creative-crysis/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Макроязык m4</title>
		<link>http://typedef.ru/2009/10/m4-macro-language/</link>
		<comments>http://typedef.ru/2009/10/m4-macro-language/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 19:33:04 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[m4]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[текст]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=403</guid>
		<description><![CDATA[Подготовка к выступлениям сразу на двух конференциях (SITOP и SofTool, если интересно) совершенно вывела из строя мой широковещательно-эпистолярный процессор. Не то чтобы мне не о чем написать (уж это-то всегда есть), просто темы все у меня какие-то трудоемкие, а кормить вас очередными горстями ссылок, не разбавляя более интеллектуальным контентом, рука не поднимается. Хотя и ссылки [...]]]></description>
			<content:encoded><![CDATA[<p>Подготовка к выступлениям сразу на двух конференциях (<a href="http://www.sitopconf.ru/" target="_blank">SITOP</a> и <a href="http://www.softool.ru/" target="_blank">SofTool</a>, если интересно) совершенно вывела из строя мой широковещательно-эпистолярный процессор. Не то чтобы мне не о чем написать (уж это-то всегда есть), просто темы все у меня какие-то трудоемкие, а кормить вас очередными горстями ссылок, не разбавляя более интеллектуальным контентом, рука не поднимается. Хотя и ссылки тоже будут, уж будьте уверены.</p>
<p>Но сейчас хочу поделиться впечатлениями от языка m4, который я внезапно выучил. Поскольку я тут понемногу готовлю мегапост (а скорее даже статью) про Autotools, то неизбежно заинтересовался, что это за странный язык m4, на котором написан Autoconf. Оказалось, на сайте GNU есть вполне <a href="http://www.gnu.org/software/m4/manual/index.html" target="_blank">приличный мануал</a> по этому поводу. Есть даже чуть менее приличный <a href="http://lib.custis.ru/index.php/M4" target="_blank">мануал на русском</a>.</p>
<p>История m4 уходит в глубину веков. Сначала появился макроязык GPM, аж в 1965 году. Потом Деннис Ричи, основательно перекроив GPM под нужды реального мира, написал m3. Затем к Ричи присоединился Керниган. Но ведь все знают, что когда Керниган и Ричи собираются вместе, обязательно выходит какая-нибудь нетленка. И вот эти два достойных мужа в едином порыве создают в 1977 году язык m4 (имя расшифровывается по аналогии с <em>i18n</em> и <em>l10n</em>). А уже в 1990 году появилась GNUтая версия. С тех пор мало что изменилось, разве что скорость выполнения немного подросла.</p>
<p>Мое знакомство с макроязыками ограничивалось до сих пор соответствующими средствами MASM на втором курсе института, да препроцессором языка C (который макро<em>языком</em> может назвать только большой оптимист). К сишному препроцессору у меня была только одна претензия: <em>на нем нельзя написать цикл</em>. Представляете, как мне мало нужно было для счастья? Поэтому осилив за 5 часов чистого времени мануал по m4, я впал в состояние прострации и глубочайшего культурного шока. Язык не был похож ни на что известное мне до этого.</p>
<p>По мере чтения мануала я проходил следующие стадии:</p>
<ol>
<li>Ммм, интересно как!</li>
<li>Сложно, блин. Черт, как же этот пример работает?..</li>
<li>Определенно, язык писали идиоты для дебилов!</li>
<li>Аааа, у меня в мозгу кавычки! Вытащите их!!!</li>
<li>Понял! Да тут же все просто!</li>
<li>Пожалуй, напишу на m4 генерацию документации для нашего проекта, а потом еще напишу парсер файлов определения локалей, а еще напишу&#8230;</li>
</ol>
<p>На последней стадии нахожусь до сих пор. Рациональных объяснений этому не нахожу. Зато понял, что автор мануала не шутил, написав в самом начале:</p>
<blockquote><p>Some people find <code>m4</code> to be fairly addictive.  They first use <code>m4</code> for simple problems, then take bigger and bigger challenges, learning how to write complex sets of <code>m4</code> macros along the way.  Once really addicted, users pursue writing of sophisticated <code>m4</code> applications even to solve simple problems, devoting more time debugging their <code>m4</code> scripts than doing real work.  Beware that <code>m4</code> may be dangerous for the health of compulsive programmers.</p></blockquote>
<p>В чем принципиальное отличие m4 от других языков? Есть языки императивные и декларативные, есть структурные, функциональные и объектно-ориентированные. Все они в конечном итоге нужны для построения программы, которая выполняет определенные действия. Еще есть языки текстовых фильтров: sed, awk и т.п. Они преобразуют входные данные в соответствии с заданными правилами. <strong>Язык m4 — порождающий.</strong> <strong>Программа, написанная на нем, не выполняется — она разворачивается в текст. </strong>Поначалу это несколько выносит мозг, но потом начинаешь ценить простоту и красоту подобных конструкций:</p>

<div class="wp_syntax"><div class="code"><pre class="m4" style="font-family:monospace;">define(`quote', `ifelse(`$#', `0', `', ``$*'')')dnl
define(`foreach',
  `_args(`$0', `$#', 3)
   foreach1($1, $2, $3)'
)
define(`arg1', `$1')
define(`foreach1',
  `ifelse(
      quote($3), `',
      `',
      `define(`$1', `arg1($3)')$2`'$0(`$1', `$2', shift(shift(shift($@))))'
    )'
)</pre></div></div>

<p>Ага, это именно то, о чем вы подумали. Цикл foreach, построенный на примитивах define, ifelse и рекурсии. Почти как в Lisp.</p>
<p>Да, синтаксис не блещет изяществом. Кроме того, <em>программа не делится на строки</em>; конец строки воспринимается буквально и попадает в порожденный текст (кроме определенных случаев). Но зато язык в действительности очень простой. В нем очень мало встроенных средств, дай бог наберется три десятка встроенных макросов. Но, как и любой язык с малым количеством базисных элементов, m4 требует определенной умственной акробатики при написании сложных конструкций. А свободное восприятие открывающих и закрывающих кавычек и нумерованных переменных a la Perl/bash/PHP — вопрос пары дней практики.</p>
<p>m4 на удивление непопулярен. В крупных проектах, за исключением Autoconf, замечен не был (UPD: еще sendmail, спасибо Юрию). Может быть, есть какие-то другие порождающие языки, намного красивее и удобнее? Пока же я вижу, что m4 очень простое и мощное средство, позволяющее сэкономить массу сил (масса сил&#8230; хм). Еще одно преимущество — m4 есть везде, где есть Autoconf, а это практически все *nix-системы.</p>
<p>Если интересно, могу развить тему и написать небольшое руководство.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/10/m4-macro-language/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>SICP</title>
		<link>http://typedef.ru/2009/09/sicp/</link>
		<comments>http://typedef.ru/2009/09/sicp/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 05:26:30 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[SICP]]></category>
		<category><![CDATA[книги]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=394</guid>
		<description><![CDATA[
Начал почитывать легендарный MIT-овский курс — Structure and Interpretation of Computer Programs. И, соответственно, понемногу делаю оттуда упражнения. Эти упражнения некоторым так нравятся, что они аж целый сайт забабахали с решениями. Не для неосиливших, ни в коем случае! Исключительно для самопроверки.
Пока терзаю первую главу и должен признаться, что если бы нас так учили на первом [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter" src="http://mitpress.mit.edu/sicp/full-text/book/cover.jpg" alt="" width="200" height="280" /></p>
<p>Начал почитывать легендарный MIT-овский курс — <a href="http://mitpress.mit.edu/sicp/full-text/book/book.html" target="_blank">Structure and Interpretation of Computer Programs</a>. И, соответственно, понемногу делаю оттуда упражнения. Эти упражнения некоторым так нравятся, что они аж <a href="http://sicp.sergeykhenkin.com/" target="_blank">целый сайт</a> забабахали с решениями. Не для неосиливших, ни в коем случае! Исключительно для самопроверки.</p>
<p>Пока терзаю первую главу и должен признаться, что если бы нас <em>так</em> учили на первом курсе (а в MIT эту книгу проходят как раз на первом курсе, хотя и не всю), то я бы сейчас был мегазвездой программирования. Хотя теперь уже я для себя в SICP новой информации почти не нахожу, но все же есть ощущение «в первый раз в первый класс». Примерно как у средневекового алхимика, попавшего на школьный урок химии: вроде бы он всю жизнь точно так же смешивал жидкости, но все-таки чего то не хватало для полного понимания того, что при этом происходит. Он, конечно, может начать вопить что-то вроде <em>«Я тут самый умный, да вы жизни не видели, да я свинец в золото тоннами, да я&#8230;»</em> (легкий такой намек на «гениальных русских программистов», которые «и так все знают»), но учительница подойдет, треснет указкой по макушке и ласково объяснит, как на самом деле все в жизни обстоит.</p>
<p>Вот и в SICP есть то самое «что-то». Без характерного для «чайниковских» книг сюсюканья, без излишнего усложнения (для первокурсников все же пишут), <em>сложные вещи объясняются простыми словами</em>. После прочтения неизменно наступает просветление. У меня даже возникло было неожиданное желание начать писать конспект. Но лень и здравый смысл победили.</p>
<p>Буду лишь иногда писать выжимки из текста и разбор интересных упражнений. Так, чисто для себя. Или будем меряться решениями?</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/sicp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Книга: «Программирование в стандарте POSIX. Часть 2»</title>
		<link>http://typedef.ru/2009/09/posix-programming-book-part2/</link>
		<comments>http://typedef.ru/2009/09/posix-programming-book-part2/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 06:52:35 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[книги]]></category>
		<category><![CDATA[реальное время]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=388</guid>
		<description><![CDATA[Название: Программирование в стандарте POSIX. Курс лекций. Учебное пособие. Часть 2.
Автор: В.А. Галатенко
Год выхода: 2005
Издательство: Интернет-Университет Информационных Технологий
Тираж: 500
Объем: 384 стр.
Обложка: твердая
Где покупал: нигде (подарок)
Как некоторые, возможно, догадались из названия, эта книга — продолжение уже описанного мною одноименного курса. Как и первая часть, эта книга имеет соответствующий курс на Интуите. Только если первая часть посвящена [...]]]></description>
			<content:encoded><![CDATA[<p><strong><a title="Галатенко В.А. Программирование в стандарте POSIX. Часть 2" rel="lightbox[pics219]" href="http://typedef.ru/wp-content/uploads/2009/09/posix2galat1.png"><img class="attachment wp-att-196 alignleft" src="http://typedef.ru/wp-content/uploads/2009/09/posix2galat1.png" alt="Галатенко В.А. Программирование в стандарте POSIX. Часть 2" width="200" height="280" /></a></strong><strong>Название:</strong> Программирование в стандарте POSIX. Курс лекций. Учебное пособие. Часть 2.<br />
<strong>Автор:</strong> В.А. Галатенко<br />
<strong>Год выхода:</strong> 2005<br />
<strong>Издательство:</strong> Интернет-Университет Информационных Технологий<br />
<strong>Тираж:</strong> 500<br />
<strong>Объем:</strong> 384 стр.<br />
<strong>Обложка:</strong> твердая<br />
<strong>Где покупал:</strong> нигде (подарок)</p>
<p>Как некоторые, возможно, догадались из названия, эта книга — продолжение уже <a href="http://typedef.ru/2009/09/posix-programming-book-part1" target="_blank">описанного мною одноименного курса</a>. Как и первая часть, эта книга имеет <a href="http://www.intuit.ru/department/se/posix2/" target="_blank">соответствующий курс на Интуите</a>. Только если первая часть посвящена програмированию в POSIX-системах вообще, то эта — <strong>программированию мобильных приложений реального времени</strong>. Да еще и в POSIX. Но на обложке об этом ничего не сказано, чтобы, не дай бог,  читателей не распугать раньше времени.</p>
<p>Системы реального времени — вообще штука непростая, скажу вам как имеющий к этому делу отношение. А уж <em>мобильное</em> (portable) программирование СРВ — и вовсе высший пилотаж. Хотя бы потому, что мобильность приложений реального времени сродни Неуловимому Джо. Обычно, когда разрабатывается СРВ, софт пишется под конкретную железяку (или уж по меньшей мере под конкретную ОС), на ней же тестируется, и если работает, то его стараются больше не трогать. Переносить уже написанную управляющую программу на другое железо вряд ли кому-то придет в голову. Тем не менее, POSIX имеет определенные средства для написания программ реального времени, и даже позволяет относительно легко написанное потом переносить.</p>
<p>Посмотрим, что нам в этой книге предложено:</p>
<ul>
<li>потоки управления и средства их синхронизации;</li>
<li>сигналы реального времени, часы, таймеры;</li>
<li>очереди сообщений, семафоры, разделяемая память;</li>
<li>файлы, отображаемые в память, типизированная память, удержание страниц в памяти;</li>
<li>приоритетное планирование;</li>
<li>асинхронный ввод-вывод;</li>
<li>рекомендательные интерфейсы;</li>
<li>трассировка приложений (не путать с пошаговой отладкой!);</li>
<li>технологические (прикладные) интерфейсы.</li>
</ul>
<p>Почему потоки и их синхронизация относятся именно к реальному времени — для меня загадка. На мой взгляд, потоки следовало бы перенести в первую книгу. Совершенно шикарно описаны сигналы с таймерами, планирование и асинхронный ввод-вывод. Остальное, в принципе, тоже хорошо, но особого восторга у меня не вызвало. Может быть, потому что я уже имел об этом представление. Скучновато было читать про трассировку, но про нее весело написать просто невозможно.</p>
<p>В целом впечатления те же, что и от первой части. Книга в первую очередь полезна как справочник, но ценна она еще и тем, что содержит пояснения по поводу не вполне ясных моментов и типичных сценариев.</p>
<p>Для общего развития вряд ли стоит читать такую книгу, но специалистам по POSIX-программированию однозначно must have. Правда, тираж совершенно мизерный, так что есть вероятность, что в продаже уже не найдешь. Читайте онлайновый курс, там то же самое.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/posix-programming-book-part2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Хаус ин да Хаус</title>
		<link>http://typedef.ru/2009/09/house-in-da-house/</link>
		<comments>http://typedef.ru/2009/09/house-in-da-house/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 07:04:02 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=385</guid>
		<description><![CDATA[В локалке начал появляться пиратски озвученный 6-й сезон Хауса, пришлось бросить все и смотреть. Что я могу сказать. Гениальность Дэвида Шора ничуть не притупилась, даже скорее наоборот. Чем дальше в лес, тем интереснее сценарии. А вот Лори ощутимо постарел. Жаль, что это похоже будет последний сезон Хауса с его участием.
К чему я это все?.. А! [...]]]></description>
			<content:encoded><![CDATA[<p>В локалке начал появляться пиратски озвученный 6-й сезон Хауса, пришлось бросить все и смотреть. Что я могу сказать. Гениальность Дэвида Шора ничуть не притупилась, даже скорее наоборот. Чем дальше в лес, тем интереснее сценарии. А вот Лори ощутимо постарел. Жаль, что это похоже будет <a href="http://www.versii.com/news/188336/" target="_blank">последний сезон Хауса с его участием</a>.</p>
<p>К чему я это все?.. А! Надо, наконец, научиться пользоваться торрентами. А то как-то недобно даже, человек 21-го века, а торрентами не пользуется. Стыд просто.</p>
<p>UPD. Научился.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/house-in-da-house/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Неизвестный ASCII</title>
		<link>http://typedef.ru/2009/09/unknown-ascii/</link>
		<comments>http://typedef.ru/2009/09/unknown-ascii/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 11:50:00 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[хитрости]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=378</guid>
		<description><![CDATA[Знаете ли вы:

чтобы из символа десятичной цифры получить ее численное значение, достаточно взять младшие 4 бита ASCII-кода этой цифры;
чтобы получить порядковый номер буквы латинского алфавита (неважно, в верхнем или нижнем регистре), достаточно взять младшие 5 бит ASCII-кода этой буквы;
чтобы перевести латинскую букву из нижнего регистра в верхний, достаточно установить 6-й бит (со смещением 5) ASCII-представления [...]]]></description>
			<content:encoded><![CDATA[<p>Знаете ли вы:</p>
<ul>
<li>чтобы <strong>из символа десятичной цифры получить ее численное значение</strong>, достаточно взять младшие 4 бита ASCII-кода этой цифры;</li>
<li>чтобы <strong>получить порядковый номер буквы латинского алфавита</strong> (неважно, в верхнем или нижнем регистре), достаточно взять младшие 5 бит ASCII-кода этой буквы;</li>
<li>чтобы <strong>перевести латинскую букву из нижнего регистра в верхний</strong>, достаточно установить 6-й бит (со смещением 5) ASCII-представления буквы в 1 (обратная операция выполняется по аналогии, сбросом этого бита).</li>
</ul>
<p>Первые два факта я не знал.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/unknown-ascii/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Лицензии открытого ПО</title>
		<link>http://typedef.ru/2009/09/opensource-licenses/</link>
		<comments>http://typedef.ru/2009/09/opensource-licenses/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 06:39:22 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[открытое ПО]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=376</guid>
		<description><![CDATA[На хабре нашел неплохой обзор основных опенсорсных лицензий. Жаль, не написали про Creative Commons и, собственно, Public Domain.
На забывайте указывать вид лицензии, когда публикуете свое открытое ПО!
]]></description>
			<content:encoded><![CDATA[<p>На хабре нашел неплохой <a href="http://habrahabr.ru/blogs/fsf/69780/" target="_blank">обзор основных опенсорсных лицензий</a>. Жаль, не написали про <a href="http://ru.wikipedia.org/wiki/%D0%9B%D0%B8%D1%86%D0%B5%D0%BD%D0%B7%D0%B8%D0%B8_Creative_Commons" target="_blank">Creative Commons</a> и, собственно, <a href="http://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D0%B5_%D0%B4%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5" target="_blank">Public Domain</a>.</p>
<p>На забывайте указывать вид лицензии, когда публикуете свое открытое ПО!</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/opensource-licenses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Языки программирования — пути эволюции</title>
		<link>http://typedef.ru/2009/09/prog-langs-evolution/</link>
		<comments>http://typedef.ru/2009/09/prog-langs-evolution/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 08:11:00 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=360</guid>
		<description><![CDATA[Вышло у меня с FallenGameR интересное обсуждение. Спором это назвать сложно, потому что в главном мы все же сходимся, но определенные разногласия имели место (в том числе и в комментариях к моему посту). Поэтому я решил, что нужно высказать свою точку зрения более развернуто, чем это обычно делается в комментариях.
Итак, язык программирования — это инструмент, [...]]]></description>
			<content:encoded><![CDATA[<p>Вышло у меня с <a href="http://fallengamer.livejournal.com" target="_blank">FallenGameR</a> интересное <a href="http://fallengamer.livejournal.com/63225.html" target="_blank">обсуждение</a>. Спором это назвать сложно, потому что в главном мы все же сходимся, но определенные разногласия имели место (в том числе и в комментариях к <a href="http://typedef.ru/2009/09/c-info-links/" target="_blank">моему посту</a>). Поэтому я решил, что нужно высказать свою точку зрения более развернуто, чем это обычно делается в комментариях.</p>
<p>Итак, язык программирования — это инструмент, с помощью которого создаются программы (да, я сегодня за К.О.). Как и всякий инструмент, он характерен тем, что:</p>
<ul>
<li>предназначен для решения определенного круга задач;</li>
<li>имеет некое соотношение «удобство — сложность освоения — производительность труда — качество продукта».</li>
</ul>
<p><em>Круг задач, решаемых с помощью инструмента, не является четко очерченным.</em> Штыковая лопата замечательно подходит для изготовления небольших ям. Еще ей можно недурственно раскроить чей-то череп. Можно косить ею траву. Саперную лопатку можно метать на небольшие расстояния. При достаточном желании можно даже лопатой играть в большой теннис. Но все же первичная область использования, в которой лопата раскрывает свои лучшие качества, — копание ям.</p>
<p>Не кажется ли вам, что все религиозные войны вокруг современных языков программирования напоминают спор о том, чем лучше подметать плац — лопатой или метлой? Иной солдатик с помощью лопаты так лихо это делает, что никакой дворник с метлой не угонится. Значит ли это, что нужно всем переходить на лопаты?</p>
<p>Ладно, хватит аналогий.</p>
<p>Возьмем множество сферических программистов в вакууме. Для каждого языка программирования тогда будут более-менее соблюдаться следующие утверждения:</p>
<ul>
<li><em>время на изучение языка</em> до определенного уровня = константа 0;</li>
<li><em>удобство использования</em> = (константа 1 для данного класса задач и языка)*sqrt(уровень владения);</li>
<li><em>производительность труда</em> = (константа 2 для данного класса задач и языка)*sqrt(уровень владения);</li>
<li><em>качество результата</em> = (константа 3 для данного класса задач и языка)*sqrt(уровень владения);</li>
<li>прочие параметры по аналогии.</li>
</ul>
<p>Полагаю, что достаточно здравого смысла, чтобы осознать справедливость этих утверждений. Например, <strong>повышение уровня владения языком позволяет повысить производительность труда. Но чем выше уровень владения, тем меньший эффект оказывает его повышение.</strong> Поэтому чтобы радикально повысить производительность для определенного класса задач, нужно просто выбрать другой язык, у которого «константа для данного класса задач и языка» будет выше.</p>
<p>Тем не менее, языки программирования развиваются, стремясь тем самым увеличить свои константы и стать универсальными. Да, было бы очень удобно изучить один язык, и решать любые возможные задачи только на нем. Но в действительности все не так гладко, как хотелось бы. Сейчас распределение примерно такое (классы задач могут пересекаться):</p>
<ul>
<li><em>системное программирование</em>: ассемблеры, C, C++;</li>
<li><em>высокопроизводительные вычисления</em>: ассемблеры, C, C++;</li>
<li><em>параллельные вычисления</em>: C, C++, Erlang, C#, &#8230;;</li>
<li><em>веб-приложения</em>: PHP, Perl, Python, Java, Ruby, JavaScript;</li>
<li><em>корпоративные приложения</em>: C#, Java;</li>
<li><em>массовые настольные приложения</em>: C++, C#, Delphi;</li>
<li><em>игры</em>: С, С++, ActionScript,  &#8230;;</li>
<li><em>вспомогательные и встраиваемые сценарии</em>: bash, Perl, Python, TCL, Lua, &#8230;</li>
</ul>
<p>Этот список я брал более-менее из головы, но, думаю, недалеко ушел от истины.</p>
<p>Выучить такую прорву языков непросто, да и ненужно. Современный программист, если не привязан к конкретному классу задач, обычно выбирает <strong>два языка: один низкоуровневый, другой высокоуровневый</strong>, да такие, чтоб могли между собой взаимодействовать, чтоб были кроссплатформенные, и чтобы имели по возможности низкий порог вхождения и высокое все остальное. Возможно, есть смысл взять еще третий язык, скриптовый.</p>
<p>Хорошим примером такой связки может быть <strong>Python+C</strong>. Они оба в плане синтаксиса несложные, но при этом первый имеет мощную библиотечную поддержку, но нетороплив, а второй позволяет выжать из компьютера все соки, но писать на нем большие программы — та еще радость (хотя опенсорсники придерживаются иного мнения). На таком тандеме можно написать почти все что угодно. На Python — GUI и основную логику, на C — низкоуровневую реализацию. Бхай-бхай.</p>
<p><strong>Другой вариант — путь обобщения.</strong> Будут развиваться универсальные языки, которые обеспечит разумный компромисс между упомянутыми выше константами. Это может быть <a href="http://en.wikipedia.org/wiki/C%2B%2B0x" target="_blank">C++0x</a>, ускоренный Python, упрощенный Perl или даже потихоньку всплывающий из пучин и обещающий всех порвать Haskell. C# — сомневаюсь. LINQ и вообще стремление к декларативщине — хорошее направление, но будет непросто преодолеть стереотип C# → Microsoft → отсутствие кроссплатформенности.</p>
<p>Этот вариант плох тем, что, как ни крути, специализированный язык в своей области эффективнее универсального.</p>
<p>Какой путь выбрать? А хрен его знает. Решайте сами.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/prog-langs-evolution/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ссылки для изучающих C</title>
		<link>http://typedef.ru/2009/09/c-info-links/</link>
		<comments>http://typedef.ru/2009/09/c-info-links/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 07:41:52 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[книги]]></category>
		<category><![CDATA[обучение]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=358</guid>
		<description><![CDATA[Вчера была нетленка, поэтому сегодня расслаблюсь и просто дам несколько ссылок на бесплатные, но очень полезные ресурсы по языку C.

C Elements of Style — сокращенный вариант старой доброй книжки лохматого года; слегка устарела, но все равно содержит массу полезного;
Learning GNU C — туториал про одноименный диалект C;
An Introduction to GCC — руководство по gcc и [...]]]></description>
			<content:encoded><![CDATA[<p>Вчера была нетленка, поэтому сегодня расслаблюсь и просто дам несколько ссылок на бесплатные, но очень полезные ресурсы по языку C.</p>
<ul>
<li><a href="http://www.oualline.com/style/index.html" target="_blank">C Elements of Style</a> — сокращенный вариант старой доброй книжки лохматого года; слегка устарела, но все равно содержит массу полезного;</li>
<li><a href="http://www.nongnu.org/c-prog-book/online/index.html" target="_blank">Learning GNU C</a> — туториал про одноименный диалект C;</li>
<li><a href="http://www.network-theory.co.uk/docs/gccintro/" target="_blank">An Introduction to GCC</a> — руководство по gcc и g++;</li>
<li><a href="http://c-faq.com" target="_blank">C FAQ</a> — огромный FAQ по языку;</li>
<li><a href="http://www.duckware.com/bugfreec/index.html" target="_blank">Writing Bug-free C Code</a> — оригинальная методология программирования на C с элементами ООП, позволяющая вроде бы упростить обнаружение ошибок; почитать интересно, но применять стремно;</li>
<li><a href="http://www.gnu.org/software/libc/manual/" target="_blank">The GNU C Library</a> — мануал по стандартной библиотеке C в исполнении GNU;</li>
<li><a href="http://www.andromeda.com/people/ddyer/topten.html" target="_blank">Top 10 Ways to be Screwed by C</a> — топ 10 сишных граблей; будет особенно полезно начинающим;</li>
<li>(<strong>UPD</strong>) <a href="http://www.cs.cf.ac.uk/Dave/C/" target="_blank">Programming in C</a> &#8212; курс лекций по С с упором на UNIX-среду;</li>
<li>(<strong>UPD</strong>) <a href="http://www.literateprogramming.com/ctraps.pdf" target="_blank">C Traps and Pitfalls</a> &#8212; статья про скользкие места C;</li>
<li>(<strong>UPD</strong>) <a href="http://www.literateprogramming.com/portableC.pdf" target="_blank">Notes on Writing Portable Programs in C</a> &#8212; статья про написание переносимых программ на C; категорически рекомендую;</li>
<li>(<strong>UPD</strong>) <a href="http://www.literateprogramming.com/indhill-cstyle.pdf" target="_blank">Indian Hill: Recommended C Style and Coding Standards</a> &#8212; рекомендации по стилю C-программ от ребят из одной лаборатории AT&amp;T.</li>
</ul>
<p>Интересные ссылки из комментов переносятся в основной пост, так что пишите.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/c-info-links/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Обработка ошибок и освобождение ресурсов на C</title>
		<link>http://typedef.ru/2009/09/c-error-handling/</link>
		<comments>http://typedef.ru/2009/09/c-error-handling/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 11:35:51 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=347</guid>
		<description><![CDATA[Некая усредненная функция обычно занимается чем-то таким:

Получает/захватывает/выделяет необходимые для работы ресурсы.
Выполняет содержательные действия.
Освобождает ресурсы.

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

Функция [...]]]></description>
			<content:encoded><![CDATA[<p>Некая усредненная функция обычно занимается чем-то таким:</p>
<ol>
<li>Получает/захватывает/выделяет необходимые для работы ресурсы.</li>
<li>Выполняет содержательные действия.</li>
<li>Освобождает ресурсы.</li>
</ol>
<p>На каждом из предыдущих этапов вдобавок должно выполняться обнаружение и обработка ошибок. И вот здесь-то и начинается самое интересное. Казалось бы, нет ничего сложного. Ну, обнаружили ошибку. Ну, обработали. В чем проблема-то? А проблема в деталях. Могут иметь место такие, например, случаи:</p>
<ol>
<li>Функция получает не один ресурс, а N. Соответственно, все полученные ресурсы нужно освободить. А если при получении <em>i</em>-го ресурса произошла ошибка, то нужно освободить только ресурсы <em>0&#8230;i-1</em>.</li>
<li>Если в содержательных действиях происходит ошибка, то перед освобождением ресурсов может понадобиться эту ошибку как-то обработать. Хорошо если такая ошибка может возникнуть только в одном месте — прямо там и обработаем. А что если в разных местах могут возникнуть ошибки, требующие одинаковой обработки? Еще после возникновения ошибки надо как-то покинуть содержательный код.</li>
<li>Если ошибка происходит в цикле со вложенностью 2 и более, то надо как-то все эти циклы покинуть.</li>
<li>Будем предполагать, что обработка ошибки не ограничивается возвратом кода ошибки, а включает какую-то более сложную обработку: запись в лог, выдача сообщений и т.п.</li>
</ol>
<p>А еще мы хотим, чтобы наш код нормально читался, быстро работал и был пригоден для дальнейшего расширения. Такие вот мы противоречивые. Что делать будем? Есть несколько вариантов.</p>
<h3><span style="color: #634b2c;">Вариант 0, «тупой»</span></h3>
<p>Что думаю, то и пишу.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>...<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...здесь объявления переменных...</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_res1<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #b1b100;">return</span> ERROR1<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_res2<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        release_res1<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> ERROR2<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_res25<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res25<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        release_res1<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        release_res2<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
        release_res24<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res24<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">// ...какой-то содержательный код...</span>
    <span style="color: #666666; font-style: italic;">// ...ошибка!</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>error<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        release_res1<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        release_res2<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
        release_res25<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res25<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> SOME_ERROR<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    release_res1<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    release_res2<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
    release_res25<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res25<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Плюсы:</strong> не обнаружены.</p>
<p><strong>Минусы:</strong></p>
<ul>
<li>массовое дублирование кода; чем больше ресурсов, тем больше дублирования;</li>
<li>выход из функции в различных точках;</li>
<li>ужасно читается;</li>
<li>большие затраты на модификацию.</li>
</ul>
<h3><span style="color: #634b2c;">Вариант 1, «правильный»</span></h3>
<p>Как прилежные студенты, мы должны были почерпнуть из умных книжек и от преподавателей, что действия, выполняемые функцией, должны находиться на <em>одном уровне абстракции</em>. Поэтому наша гипотетическая функция должна выглядеть как-то так:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>...<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">struct</span> data data<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> r_code<span style="color: #339933;">;</span>
&nbsp;
    r_code <span style="color: #339933;">=</span> get_resources<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>r_code<span style="color: #009900;">&#41;</span> do_work<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>r_code<span style="color: #009900;">&#41;</span> handle_error<span style="color: #009900;">&#40;</span>r_code<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    release_resources<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> r_code<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Что там делают функции <code>get_resources()</code>, <code>do_work()</code>, <code>handle_error()</code> и <code>release_resources()</code> — нам неинтересно. Конечно, приведенный выше код — всего лишь демонстрация идеи. Очевидно, если все функции писать в таком духе, то до нижнего уровня, который, собственно, и делает фактическую работу, мы никогда не дойдем. Так и погрязнем в бесконечных слоях абстракций. Поэтому вместо <code>do_work()</code> обычно пишется компактный код, выполняющий требуемую работу, но без излишнего углубления в детали.</p>
<p><strong>Плюсы:</strong></p>
<ul>
<li>компактный код, хорошая читабельность;</li>
<li>возможность повторного использования (например, функции обработки ошибок);</li>
<li>одна точка выхода;</li>
<li>хорошо поддается рефакторингу.</li>
</ul>
<p><strong>Минусы:</strong></p>
<ul>
<li>относительно низкая эффективность;</li>
<li>наличие синтетической структуры данных (<code>struct data</code>), хранящей состояние ресурсов.</li>
</ul>
<h3><span style="color: #634b2c;">Вариант 2, «тру-хакерский»</span></h3>
<p>Настоящие хакеры не боятся <code>goto</code>. Настоящие хакеры плевать хотели на предрассудки. Мнение о вредности <code>goto</code> было специально распространено ими среди начинающих; <code>goto</code> в коде хакера — как катана в руках самурая: новичок может покалечить себя, а мастер — всех остальных.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>...<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...здесь объявления переменных...</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_res1<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        ret <span style="color: #339933;">=</span> ERROR1<span style="color: #339933;">;</span>
        <span style="color: #b1b100;">goto</span> exit<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_res2<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        ret <span style="color: #339933;">=</span> ERROR2<span style="color: #339933;">;</span>
        <span style="color: #b1b100;">goto</span> exit1<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_res25<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res25<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        ret <span style="color: #339933;">=</span> ERROR25<span style="color: #339933;">;</span>
        <span style="color: #b1b100;">goto</span> exit24<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">// ...какой-то содержательный код...</span>
    <span style="color: #666666; font-style: italic;">// ...ошибка!</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>error<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        ret <span style="color: #339933;">=</span> SOME_ERROR<span style="color: #339933;">;</span>
        <span style="color: #b1b100;">goto</span> error<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #b1b100;">goto</span> exitOK<span style="color: #339933;">;</span>
&nbsp;
error<span style="color: #339933;">:</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
&nbsp;
exitOK<span style="color: #339933;">:</span>
    release_res25<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res25<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
exit24<span style="color: #339933;">:</span>
    release_res24<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res24<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// ...</span>
exit2<span style="color: #339933;">:</span>
    release_res2<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
exit1<span style="color: #339933;">:</span>
    release_res1<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
exit<span style="color: #339933;">:</span>
    <span style="color: #b1b100;">return</span> ret<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Идея схожа с предыдущим вариантом: <em>локализовать места обработки ошибок и освобождения ресурсов</em>. За счет fallthrough-стиля освобождение происходит очень изящно. Главная проблема при использовании goto для обработки ошибок и освобождения ресурсов — соблюдать меру. Не зря ведь в моем примере 25 ресурсов: в случае использования варианта №1 размер кода не зависит от их количества, здесь же мы получаем спагетти. Использование <code>goto</code> позволяет сократить код по сравнению с вариантом №0, но таит в себе опасность бесконечного увеличения размера функции, так как возможности рефакторинга здесь ограничены.</p>
<p>Такой подход можно встретить, например, в ядрах Linux и FreeBSD.</p>
<p><strong>Плюсы:</strong></p>
<ul>
<li>неплохая читабельность при аккуратной реализации;</li>
<li>высокая эффективность;</li>
<li>одна точка выхода.</li>
</ul>
<p><strong>Минусы:</strong></p>
<ul>
<li>ограниченные возможности рефакторинга: части функции жестко связаны между собой переходами;</li>
<li>при дальнейшем развитии функции она может стать плохо читаемой.</li>
</ul>
<h3><span style="color: #634b2c;">Вариант 3, «gotoфобский»</span></h3>
<p>Еще один вариант, также часто встречающийся в реальном коде, — использование цикла в качестве конструкции, ограничивающей «зону безошибочного выполнения», и оператора <code>break</code> в качестве аналога <code>goto</code> из предыдущего варианта.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>...<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// ...здесь объявления переменных...</span>
&nbsp;
    <span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_res1<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            ret <span style="color: #339933;">=</span> ERROR1<span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_res2<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            ret <span style="color: #339933;">=</span> ERROR2<span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>get_res25<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res25<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            ret <span style="color: #339933;">=</span> ERROR25<span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #666666; font-style: italic;">// ...какой-то содержательный код...</span>
        <span style="color: #666666; font-style: italic;">// ...ошибка!</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>error<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            ret <span style="color: #339933;">=</span> SOME_ERROR<span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>ret<span style="color: #009900;">&#41;</span>
        ret <span style="color: #339933;">=</span> handle_error<span style="color: #009900;">&#40;</span>ret<span style="color: #339933;">,</span> ...<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>res1_allocated<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        release_res1<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>res2_allocated<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res2<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        release_res2<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// ...</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>res25_allocated<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res25<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        release_res25<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>res25<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> ret<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Признаться, я долгое время был сторонником такого подхода, пока не поумнел.</p>
<p><strong>Плюсы:</strong></p>
<ul>
<li>отсутствует goto;</li>
<li>слабая связность фрагментов функции, хорошо поддается рефакторингу;</li>
<li>одна точка выхода.</li>
</ul>
<p><strong>Минусы:</strong></p>
<ul>
<li>требуется отслеживать состояние ресурсов с помощью флагов, некорректных значений или чего-то еще;</li>
<li>проблемы с выходом из вложенных циклов, приходится или многократно проверять код ошибки, или использовать goto;</li>
<li>средняя эффективность.</li>
</ul>
<h3><span style="color: #634b2c;">Итого</span></h3>
<p>Конечно, можно придумать еще мульён вариантов, один другого краше. Есть даже отдельная когорта любителей «метапрограммирования» (<a href="http://www.nicemice.net/cexcept/" target="_blank">тыц</a>, <a href="http://www.on-time.com/ddj0011.htm" target="_blank">тыц</a>). Я такие вещи не понимаю и не одобряю. Если уж есть такая тяга к синтаксису try-catch, то почему бы не пользоваться C++? В подавляющем большинстве случаев нет причины, которая позволяла бы пользоваться C, но исключала возможность использования C++ (хотя у меня именно такой редкий случай).</p>
<p>Чем же пользоваться? Мое мнение такое:</p>
<ul>
<li>всегда писать согласно варианту 1;</li>
<li>если в результате работает слишком медленно, переписать отдельные функции (или даже модули) по варианту 2.</li>
</ul>
<p>Жду гневные, но конструктивные комментарии.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/c-error-handling/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>День рождения Linux</title>
		<link>http://typedef.ru/2009/09/linux-birthday/</link>
		<comments>http://typedef.ru/2009/09/linux-birthday/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 18:31:33 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[история]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=339</guid>
		<description><![CDATA[Версия 0.01 вышла 17 сентября 1991 года. Сегодня совершеннолетие!
Всем срочно sudo drink !

]]></description>
			<content:encoded><![CDATA[<p>Версия 0.01 вышла 17 сентября 1991 года. Сегодня совершеннолетие!</p>
<p>Всем срочно <strong>sudo drink</strong> !<strong><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/linux-birthday/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Почему не стоит учиться на программиста</title>
		<link>http://typedef.ru/2009/09/why-not-worth-learning-programmin/</link>
		<comments>http://typedef.ru/2009/09/why-not-worth-learning-programmin/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 08:31:18 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[работа]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=326</guid>
		<description><![CDATA[Программисты
Давным-давно жили-были Программисты. Были они умные, знали дофига чего такого, что обычным людям ни в жисть не понять, и было их мало. Оттого спросом они пользовались необычайным, зарабатывали кучу денег и вообще считались уважаемыми людьми. Еще были Пользователи, которые тоже умели программировать. Даже больше того, в то время собственно пользование компьютером заключалось в написании для [...]]]></description>
			<content:encoded><![CDATA[<h3><span style="color: #634b2c;">Программисты</span></h3>
<p>Давным-давно жили-были <em>Программисты</em>. Были они умные, знали дофига чего такого, что обычным людям ни в жисть не понять, и было их мало. Оттого спросом они пользовались необычайным, зарабатывали кучу денег и вообще считались уважаемыми людьми. Еще были <em>Пользователи</em>, которые тоже умели программировать. Даже больше того, в то время собственно <strong>пользование компьютером заключалось в написании для него программ</strong>. Каждому Пользователю приходилось учить Фортран или Бейсик, иначе компьютер превращался просто в бесполезный предмет интерьера. Конечно, до уровня Программистов Пользователям было как пешком до Луны, потому что для Пользователя программирование было лишь инструментом, подспорьем в проведении необходимых вычислений и анализа, тогда как Программист занимался написанием программ профессионально. Короче говоря, было такое счастливое время, и все были довольны. Но Программисты все же были круче.</p>
<p>Дальнейшая эволюция была стремительна и беспощадна. Суть революции хорошо выражается семантикой оператора shift  в некоторых скриптовых языках. Вместе с ростом числа компьютеров на душу населения росло и число пользователей, которые не умели программировать (если вообще хоть что-то умели). В то же время Программисты в связи с определенными геополитическими изменениями стали массово покидать родные края. Их нишу понемногу заняли Пользователи, умеющие программировать. В результате мы получили немоверную массу пользователей, которые не умеют ничего, некоторое количество Пользователей, которые умеют программировать, но не то чтобы очень сильны в этом, и тонкий-претонкий слой Программистов-мазохистов.</p>
<p>Да, вузы исправно каждый год выпускают тысячи молодых специалистов информационных специальностей. Но вот ведь какой парадокс: учили студента на Программиста, а получился Пользователь. Потому что <strong>воспитать Программиста может только другой Программист</strong>, а таких почти не осталось. Замкнутый круг.</p>
<h3><span style="color: #634b2c;">Софт</span></h3>
<p>Но это только одна сторона. Если посмотреть на рынок ПО, то несложно заметить, что ничего нового на нем фактически не появляется. Были эпохальные продукты вроде Windows, Office, <em>1C Что-То-Там</em> и тому подобных монстров, которые закрыли собой гигантские ниши. Все! Нужно просто признать: <strong>эпоха разработки массового софта заканчивается</strong>. Все, что нужно среднестатистическому пользователю, уже написано. Зачем же тогда Microsoft год за годом печет новые Офисы и Винды? Что, старые чем-то плохи? Нет! <em>Просто им хочется кушать.</em> Поэтому они развешивают тонны маркетинговой лапши на нежные юзерские уши, лишь бы только кто-нибудь купил их новый Офис. Который от N предыдущих версий отличается только по-другому расположенными кнопками и приведенной в соответствие с веяниями моды цветовой гаммой. Без сомнения, за это стоит отдавать триста баксов!</p>
<p>Конечно, я преувеличиваю. В мире есть еще что разрабатывать.</p>
<ul>
<li><strong>Веб-приложения</strong>. Сейчас «программист» уже в головах обывателей является синонимом «веб-программиста». Только вот беда — вердикт «уже написано» все чаще звучит и здесь. Народ уже не знает, что бы такое написать, поэтому пишет всякую ерунду, благо процесс ее создания упростился невероятно. Операционная система в браузере? Не смешите.</li>
<li><strong>Корпоративный софт</strong>. Опять-таки, загибающаяся область. Один универсальный инструмент (1С, SAP) и толпа низкоквалифицированных адептов (<em>1С-«программист»</em>, хо-хо) легко заменяет большинство корпоративок. Остаются лишь только всякие банки, авиаперевозчики и т.п., которые поступили мудро, придумав настолько сложные бизнес-процессы, что хрен напишешь обобщенный инструмент. А если поднапрячься и все же написать, получится VisualStudio.</li>
<li><strong>Специфический софт</strong>. Драйверы, управляющий софт, firmware. Пожалуй, здесь пока еще все нормально. Появляются новые железки и комплексы — должен появиться и софт для них, никуда не денешься.</li>
</ul>
<h3><span style="color: #634b2c;">Итого</span></h3>
<p>У вменяемого читателя должен на этом месте возникнуть в голове диссонанс. Как так — писать больше нечего, а программисты все работают (и неплохо зарабатывают). Ничего удивительного. <strong>Программисты работают по инерции.</strong></p>
<p>С одной стороны, компании все еще думают, что стоит только нанять программиста, как все проблемы исчезнут. Видимо, сказываются смутные воспоминания о золотом веке софтостроения в 90-х годах. А поскольку у нас в стране бизнес основан на связях и откатах, а не на грамотном управлении, то никто и не позаботился посчитать, действительно ли найм программистов за большие деньги приносит прибыль. Конечно, к софтверным компаниям (которые в данном случае выступают в роли этаких метапрограммистов) это не относится.</p>
<p>С другой стороны, программисты все еще считают себя самыми востребованными специалистами на свете и всячески это мнение поддерживают. Вместе с тем их профессионализм стремительно падает (см. выше), а самооценка столь же стремительно растет. «Российских Программистов» это касается в первую очередь. Г-н Медведев вон считает, что «наши программисты — самые программистые». А на деле выходит, что они (мы) сливаем по всем статьям западным коллегам, а денег хотим много.</p>
<p>Так что готовьтесь. Пройдет еще несколько лет (думаю, от 5 до 15), и запас инерции кончится. Собственно, зарплаты программистов уже падают (и в рублях, и в долларах), как и количество вакансий. А скоро мы получим:</p>
<ul>
<li>в разы меньшее количество рабочих мест;</li>
<li>гораздо более высокие требования к квалификации;</li>
<li>жесточайшую конкуренцию.</li>
</ul>
<p>Приходите через пять лет, проверим.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/why-not-worth-learning-programmin/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Книга про Python 3</title>
		<link>http://typedef.ru/2009/09/python3-book/</link>
		<comments>http://typedef.ru/2009/09/python3-book/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 17:17:49 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[книги]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=322</guid>
		<description><![CDATA[Истинно вам глаголю, третий питон станет массовым, когда на него перейдет Django. Пока это, безусловно, очень перспективный язык, но не хватает ему критической массы разработчиков (которую, как мне кажется, уже набрал Python 2.x). И еще один важный шаг — включение сабжа в репозитории линуксов. Вот тогда-то и начнется!
А пока Марк Пилгрим закончил работу над своей [...]]]></description>
			<content:encoded><![CDATA[<p>Истинно вам глаголю, третий питон станет массовым, когда на него перейдет <a href="http://www.djangoproject.com/" target="_blank">Django</a>. Пока это, безусловно, очень перспективный язык, но не хватает ему критической массы разработчиков (которую, как мне кажется, уже набрал Python 2.x). И еще один важный шаг — включение сабжа в репозитории линуксов. Вот тогда-то и начнется!</p>
<p>А пока Марк Пилгрим закончил работу над своей новой книгой — <a href="http://diveintopython3.org/" target="_blank">Dive Into Python 3</a>. Написана приятным языком, с юмором, читается легко, примеры программ адекватные. Приятно, что по целой главе уделено <a href="http://typedef.ru/2009/02/tdd-unit-tests/" target="_blank">блочному тестированию</a> и рефакторингу. Да и вообще, очень жизненно излагает. Внушает, как говорил один персонаж из нашего демократического прошлого по имени Х. М.</p>
<p>Особенно порадовало то, что книгу можно бесплатно и совершенно легально скачать в формате PDF или HTML. Энтузиасты могут даже читать ее прямо на означенном выше сайте. Очевидно, именно для таких людей автор поместил на страницу берущие за душу строки:</p>
<blockquote><p>This site is optimized for Lynx just because fuck you.<br />
I’m told it also looks good in graphical browsers.</p></blockquote>
<p>На этой оптимистичной ноте разрешите откланяться.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/python3-book/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Eclipse 3.5 в Fedora 11</title>
		<link>http://typedef.ru/2009/09/eclipse-3-5-v-fedora-11/</link>
		<comments>http://typedef.ru/2009/09/eclipse-3-5-v-fedora-11/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 04:28:04 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Eclipse]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=320</guid>
		<description><![CDATA[Окончательно пришел к выводу, что нет никакого смысла пользоваться Eclipse, который ставится из репозиториев Fedora 11. Для меня остается загадкой, что сподвигло авторов дистрибутива упорно держаться за версию 3.4.2 вместо новенькой 3.5. Дело не в неудовлетворенных зависимостях, ясное дело. Просто какие-то политические соображения.
Есть еще один минус Eclipse из репов: почему-то у меня не работает встроенный [...]]]></description>
			<content:encoded><![CDATA[<p>Окончательно пришел к выводу, что нет никакого смысла пользоваться Eclipse, который ставится из репозиториев Fedora 11. Для меня остается загадкой, что сподвигло авторов дистрибутива упорно держаться за версию 3.4.2 вместо новенькой 3.5. Дело не в неудовлетворенных зависимостях, ясное дело. Просто какие-то политические соображения.</p>
<p>Есть еще один минус Eclipse из репов: почему-то у меня не работает встроенный менеджер плагинов. Через yum ставится, а через Eclipse нет. А еще у нас на работе умельцы написали обалденный плагин для удаленной отладки на нашем процессоре, но ставится он только на 3.5.</p>
<p>В результате я снес все подчистую, скачал с <a href="http://eclipse.org" target="_blank">eclipse.org</a> самую свежую версию, воспользовался замечательным репозиторием дополнений <a href="http://download.cloudsmith.com/galileoplus" target="_blank">CloudSmith</a> и счастье пришло.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/eclipse-3-5-v-fedora-11/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>День программиста</title>
		<link>http://typedef.ru/2009/09/programmers-day/</link>
		<comments>http://typedef.ru/2009/09/programmers-day/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 16:17:22 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=317</guid>
		<description><![CDATA[Сегодня для всех программистов особенный день. И совершенно не имеет значения, признан ли он официально, или нет. Для всех нас он будет подтверждением того, что мы существуем — странные люди, говорящие на разных языках, но при этом очень похожие. Любящие порядок и логику, хранящие в головах огромный объем информации, те, у кого иная манера мышления, кто [...]]]></description>
			<content:encoded><![CDATA[<p>Сегодня для всех программистов особенный день. И совершенно не имеет значения, признан ли он официально, или нет. Для всех нас он будет подтверждением того, что мы существуем — странные люди, говорящие на разных языках, но при этом очень похожие. Любящие порядок и логику, хранящие в головах огромный объем информации, те, у кого иная манера мышления, кто смеется над непонятными для остальных шутками, кто может находить удовольствие в абстракциях и красоту в строках кода. И конечно же, у всех нас есть парадоксальная особенность: нам плятят за то, что мы развлекаемся.</p>
<p>Не знаю, как должен отмечать свой профессиональный праздник тру-программист, но лично я гулял с женой в парке, катался на колесе обозрения, кормил хлебом уток и рыб, а еще случайно попал на бесплатный концерт духового оркестра. А еще я не написал за день ни строчки кода. И не собираюсь. Праздник ведь.</p>
<p>А вы как отмечали 0&#215;100-ый день в году?</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/programmers-day/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Перенаправление ввода-вывода в bash</title>
		<link>http://typedef.ru/2009/09/bash-redirection/</link>
		<comments>http://typedef.ru/2009/09/bash-redirection/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 08:01:40 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[UNIX]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=307</guid>
		<description><![CDATA[Когда я начинал изучать написание сценариев bash, была такая штука, которую я никак не мог понять — перенаправление ввода-вывода. Снова и снова я перечитывал документацию, дословно переписывал оттуда положенные циферки и амперсанды, но никак не мог понять расстановки этих самых магических символов.
Я предполагаю, что вы знакомы с понятиями «файловый дескриптор», «поток ввода (вывода)», «конвейер» и т.д., [...]]]></description>
			<content:encoded><![CDATA[<p>Когда я начинал изучать написание сценариев bash, была такая штука, которую я никак не мог понять — перенаправление ввода-вывода. Снова и снова я перечитывал документацию, дословно переписывал оттуда положенные циферки и амперсанды, но никак не мог понять расстановки этих самых магических символов.</p>
<p>Я предполагаю, что вы знакомы с понятиями «файловый дескриптор», «поток ввода (вывода)», «конвейер» и т.д., но просто никак не можете запомнить, как всем этим пользоваться. На самом деле все просто. Смотрите.</p>
<p>Команда перенаправления вывода позволяет все, что записывается в один файловый дескриптор (<strong>откуда</strong>), записать вместо этого в другой файловый дескриптор (<strong>куда</strong>):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">откуда <span style="color: #000000; font-weight: bold;">&gt;</span> куда</pre></div></div>

<p>Что может быть на месте <strong>откуда</strong>:</p>
<ul>
<li><strong>ничего</strong>: перенаправление из дескриптора 1 (stdout);</li>
<li><strong>i</strong>: перенаправление из дескриптора i;</li>
<li><strong>&amp;</strong>: перенаправляются сразу <code>stdout</code> и <code>stderr</code>.</li>
</ul>
<p>Что может быть на месте <strong>куда</strong>:</p>
<ul>
<li><strong>&amp;j</strong>: перенаправление в дескриптор j;</li>
<li><strong>имя файла</strong>: файл открывается в режиме записи, и перенаправление осуществляется в него.</li>
</ul>
<p>Если используется оператор перенаправления &gt;&gt; (дописать в конец) вместо &gt; (очистить и писать сначала), то <strong>куда</strong> может быть только именем файла.</p>
<p>Указываемый дескриптор не обязательно должен быть открыт. Номера с 3 по 9 можно использовать как «перевалочные пункты»; открытые файлы получают дескрипторы, начиная с 10.</p>
<p>Перенаправление ввода работает очень похоже:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">куда <span style="color: #000000; font-weight: bold;">&lt;</span> откуда</pre></div></div>

<p>Теперь при чтении из <strong>куда</strong> на самом деле чтение будет происходить из <strong>откуда</strong>. Тут по сравнению с перенаправлением вывода все наоборот. <strong>Куда</strong> может быть пустым (<code>stdin</code>) или номером дескриптора. Заметьте, что символ &amp; здесь уже не годится — нельзя читать из двух потоков сразу. <strong>Откуда</strong> может быть или вида &amp;i, или именем файла, который при этом открывается для чтения.</p>
<p>Указанное в команде перенаправление работает только для одной строки сценария; чтобы перенаправление было постоянным, нужно выполнить его с помощью <code>exec</code>. В одной строке можно указывать несколько перенаправлений, причем они комбинируются. Например:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ps</span> <span style="color: #660033;">-aF</span> <span style="color: #000000; font-weight: bold;">&gt;</span> myfile <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">1</span></pre></div></div>

<p>Здесь сначала <code>stdout</code> перенаправляется в файл, а затем <code>stderr</code> перенаправляется в <code>stdout</code>. В результате и <code>stdout</code>, и <code>stderr</code> перенаправляются в файл. Замечу, что перенаправление выполняется по порядку. То есть, такая команда будет работать по-другому:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ps</span> <span style="color: #660033;">-aF</span> <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">&gt;</span> myfile</pre></div></div>

<p>Здесь <code>stderr</code> будет выведет на консоль. Правило простое: <em>перенаправление происходит в текущую конечную точку перенаправления дескриптора</em> (если не поняли, прочитайте предложение еще раз).</p>
<p>Еще один тонкий момент: как быть с <strong>конвейерами</strong>? Распространяется ли действие перенаправления на весь конвейер? Правила просты:</p>
<ul>
<li>перенаправление действует только на ту команду в конвейере, где оно задано;</li>
<li>команда выдает в конвейер данные, выведенные в дескриптор 1 (с учетом перенаправлений);</li>
<li>команда берет из конвейера данные, полученные из дескриптора 0 (с учетом перенаправлений).</li>
</ul>
<p>Например, вот так можно перенаправить поток ошибок в конвейер:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ps</span> <span style="color: #660033;">-aF</span> <span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">1</span> <span style="color: #000000;">1</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span> <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">3</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> something</pre></div></div>

<p>Здесь <code>stderr</code> и <code>stdout</code> фактически меняются местами.</p>
<p>Конечно, можно много чего еще сказать по поводу перенаправления: про одновременное перенаправление и ввода, и вывода, про перенаправление блока команд, про перенаправление с помощью <code>exec</code>, про закрытие дескрипторов и т.д. Но тогда пост получится слишком объемным, и им неудобно будет пользоваться как справкой. Если у вас есть какие-то вопросы, готов ответить в комментариях. За найденные ошибки также буду признателен.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/bash-redirection/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Развлечения на Си</title>
		<link>http://typedef.ru/2009/09/c-joy/</link>
		<comments>http://typedef.ru/2009/09/c-joy/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 06:41:47 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[хитрости]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=302</guid>
		<description><![CDATA[FallenGamer своим постом вызвал у меня острый приступ ностальгии:

int i = 10;
while &#40;i --&#38;gt; 0&#41; // &#34;оператор --&#38;gt;&#34;
    foo&#40;&#41;;

Хотя его пост был про C#, но такая штука сработает практически во всех C-подобных языках. Я сразу вспомнил еще пару подобных забавных конструкций. Например, интересное определение макросов TRUE и FALSE:

#define TRUE ('/'/'/')
#define FALSE ('-'-'-')

или [...]]]></description>
			<content:encoded><![CDATA[<p>FallenGamer <a href="http://fallengamer.livejournal.com/61490.html" target="_blank">своим постом</a> вызвал у меня острый приступ ностальгии:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">10</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">--&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">// &quot;оператор --&amp;gt;&quot;</span>
    foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Хотя его пост был про C#, но такая штука сработает практически во всех C-подобных языках. Я сразу вспомнил еще пару подобных забавных конструкций. Например, интересное определение макросов TRUE и FALSE:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define TRUE ('/'/'/')</span>
<span style="color: #339933;">#define FALSE ('-'-'-')</span></pre></div></div>

<p>или «оператор приведения к bool»:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> a <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> b <span style="color: #339933;">=</span> <span style="color: #0000dd;">123</span><span style="color: #339933;">;</span>
a <span style="color: #339933;">=</span> <span style="color: #339933;">!!</span>a<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 0</span>
b <span style="color: #339933;">=</span> <span style="color: #339933;">!!</span>b<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 1</span></pre></div></div>

<p>А еще вот — логический XOR:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">!</span>a <span style="color: #339933;">!=</span> <span style="color: #339933;">!</span>b</pre></div></div>

<p>Очень вас прошу, не пользуйтесь в своем коде чем-либо подобным&#8230; Я уж и не говорю про примеры из книги «Алгоритмические трюки для программистов».</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/c-joy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Четкие шрифты в Linux</title>
		<link>http://typedef.ru/2009/09/linux-sharp-fonts/</link>
		<comments>http://typedef.ru/2009/09/linux-sharp-fonts/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 05:42:29 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=287</guid>
		<description><![CDATA[Не знаю, как всех, но лично меня страшно раздражают сглаженные шрифты. Ну поаккуратнее они, ну покрасивее. Ну и что? Читаются же ужасно! К тому же, поверьте очкарику со стажем, нечеткие буквы — прямой путь к перенапряжению глаз. Мозг считает, что плохо сфокусировал глаза, и поэтому весь день только и занимается тем, что пытается их перефокусировать. [...]]]></description>
			<content:encoded><![CDATA[<p>Не знаю, как всех, но лично меня страшно раздражают сглаженные шрифты. Ну поаккуратнее они, ну покрасивее. Ну и что? Читаются же ужасно! К тому же, поверьте очкарику со стажем, нечеткие буквы — прямой путь к перенапряжению глаз. Мозг считает, что плохо сфокусировал глаза, и поэтому весь день только и занимается тем, что пытается их перефокусировать. Да что там, для меня даже несглаженный шрифт на подключенном через аналоговый выход мониторе чересчур нечеткий.</p>
<p>В Windows шрифтовым станда<a title="Sharp Fonts" rel="lightbox[pics287]" href="http://typedef.ru/wp-content/uploads/2009/09/sharpfonts.png"><img class="attachment wp-att-288 alignleft" src="http://typedef.ru/wp-content/uploads/2009/09/sharpfonts.thumbnail.png" alt="Sharp Fonts" width="200" height="124" /></a>ртом де-факто является True Type. В Linux за отображение шрифтов отвечает пакет freetype, который поддерживает кучу стандартов шрифтов, но вот нормальное отображение True Type в нем обычно отключено по юридическим соображениям. Поэтому, если просто отключить антиалиасинг, то шрифты будут четкими, но фантастически уродливыми (даже если взять виндовые).</p>
<p>Чтобы таки получить шрифты «как в Windows», мне достаточно было выполнить нехитрые действия:</p>
<ol>
<li>Отключить штатное сглаживание и поставить экранное разрешение 96 dpi.</li>
<li>Перекомпилировать freetype, взяв его с <a href="http://www.freetype.org/">http://www.freetype.org/</a> (желательно версию, которая сейчас установлена). При этом прочитать docs/TRUETYPE, в котором описаны необходимые действия, которые нужны для корректной обработки True Type (нужно раскомментировать одну строку в одном заголовочнике). Не забыть указать префикс (у меня /usr) при вызове ./configure.</li>
<li>Перезагрузить иксы.</li>
<li>Enjoy!</li>
</ol>
<p>Минус только один: при обновлении freetype придется проделать действия заново.</p>
<p>Подробнее об этом процессе можно почитать <a href="http://linuxforum.ru/index.php?showtopic=12690" target="_blank">здесь</a>. <a href="http://linuxforum.ru/index.php?showtopic=12690"></a> Шрифты True Type можно взять <a href="http://www.sharpfonts.com/" target="_blank">тут</a>.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/linux-sharp-fonts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Поддержка OpenID в комментариях</title>
		<link>http://typedef.ru/2009/09/openid-comments/</link>
		<comments>http://typedef.ru/2009/09/openid-comments/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 09:56:24 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[блог]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=293</guid>
		<description><![CDATA[Теперь при написании комментариев можно пользоваться идентификатором OpenID! Напоминаю, что у всех пользователей ЖЖ он есть автоматически.
Будут вопросы — обращайтесь. Баг-репорты приветствуются.
UPD. Теперь в комментариях отображаются юзерпики ЖЖ и Gravatar&#8217;ы.
]]></description>
			<content:encoded><![CDATA[<p>Теперь при написании комментариев можно пользоваться идентификатором OpenID! Напоминаю, что у всех пользователей ЖЖ он есть автоматически.</p>
<p>Будут вопросы — обращайтесь. Баг-репорты приветствуются.</p>
<p>UPD. Теперь в комментариях отображаются юзерпики ЖЖ и Gravatar&#8217;ы.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/openid-comments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Книга: «Программирование в стандарте POSIX. Часть 1»</title>
		<link>http://typedef.ru/2009/09/posix-programming-book-part1/</link>
		<comments>http://typedef.ru/2009/09/posix-programming-book-part1/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 06:36:42 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[книги]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=275</guid>
		<description><![CDATA[Название: Программирование в стандарте POSIX. Курс лекций. Учебное пособие. Часть 1.
Автор: В.А. Галатенко
Год выхода: 2004
Издательство: Интернет-Университет Информационных Технологий
Тираж: 2000
Объем: 560 стр.
Обложка: твердая
Где покупал: нигде (подарок)
Книгу мне подарил лично Владимир Антонович, поэтому я посчитал себя обязанным ее всю прочитать и поделиться впечатлениями с «уважаемым all».
Книга является дословным бумажным воплощением одноименного курса на Интуите. Так что все [...]]]></description>
			<content:encoded><![CDATA[<p><strong><a title="Галатенко В.А. Программирование в стандарте POSIX. Часть 1" rel="lightbox[pics219]" href="http://typedef.ru/wp-content/uploads/2009/06/posixprog.png"><img class="attachment wp-att-196 alignleft" src="http://typedef.ru/wp-content/uploads/2009/06/posixprog.png" alt="Галатенко В.А. Программирование в стандарте POSIX. Часть 1" width="200" height="280" /></a>Название:</strong> Программирование в стандарте POSIX. Курс лекций. Учебное пособие. Часть 1.<br />
<strong>Автор:</strong> В.А. Галатенко<br />
<strong>Год выхода:</strong> 2004<br />
<strong>Издательство:</strong> Интернет-Университет Информационных Технологий<br />
<strong>Тираж:</strong> 2000<br />
<strong>Объем:</strong> 560 стр.<br />
<strong>Обложка:</strong> твердая<br />
<strong>Где покупал:</strong> нигде (подарок)</p>
<p>Книгу мне подарил лично Владимир Антонович, поэтому я посчитал себя обязанным ее всю прочитать и поделиться впечатлениями с «уважаемым all».</p>
<p>Книга является дословным бумажным воплощением <a href="http://www.intuit.ru/department/se/pposix/" target="_blank">одноименного курса на Интуите</a>. Так что все сказанное в равной степени справедливо и для оного курса.</p>
<p>Неоднозначные у меня остались ощущения после прочтения. С одной стороны, голову аж распирает от подробностей и тонкостей. С другой стороны, такой объем информации запомнить практически невозможно. Сомневаюсь, что кто-то пользуется каждой перечисленной в книге функцией хотя бы раз на протяжении года. Проходит неделя, две — и знания понемногу выветриваются по причине невостребованности.</p>
<p>Лично я теперь пользуюсь этим курсом как <strong>прекрасно откомментированным и снабженным примерами man&#8217;ом</strong>. Программирую, например, что-то связанное со взаимодействием процессов — сразу лезу в соответствующий раздел (кстати, книга в плане поиска нужного места гораздо удобнее онлайн-версии), читаю все подряд и дальше уже с полнейшей уверенностью пишу все как надо. Что выгодно отличает книгу от man&#8217;а, так это комплексная подача материала: описываются не отдельные функции, а их работа в контексте общей проблемы. Да еще и примеры достаточно объемные.</p>
<p>Приятно, что книга не стала пересказом стандарта. Например, по главе про shell вполне можно научиться основам программирования командных сценариев. По каждой теме рассказано не только <em>как</em>, но и <em>зачем</em>.</p>
<p>Существует еще и вторая часть книги, в которой рассказывается о «продвинутых» возможностях: потоки, средства реального времени, асинхронный ввод-вывод, трассировка и т.д. Уже взялся ее читать, ждите обзор.</p>
<p><strong>Минусы:</strong></p>
<ul>
<li>код набран слишком крупным шрифтом, ширины страницы часто не хватает, да и по вертикали на странице помещается мало строк.</li>
</ul>
<p><strong>Плюсы:</strong></p>
<ul>
<li>подробное, но при этом очень сжатое изложение; никакой воды, только информация;</li>
<li>рассматриваются многие неочевидные моменты — видно глубокое понимание материала;</li>
<li>отличное качество печати и переплета.</li>
</ul>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/posix-programming-book-part1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Обновление</title>
		<link>http://typedef.ru/2009/09/wordpress-update/</link>
		<comments>http://typedef.ru/2009/09/wordpress-update/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 20:13:15 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[блог]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=284</guid>
		<description><![CDATA[Обновил Wordpress. Все должно выглядеть как раньше. Если заметите косяки, пишите.
]]></description>
			<content:encoded><![CDATA[<p>Обновил Wordpress. Все должно выглядеть как раньше. Если заметите косяки, пишите.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/wordpress-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Паттерны написания серверов</title>
		<link>http://typedef.ru/2009/09/highload-servers-patterns/</link>
		<comments>http://typedef.ru/2009/09/highload-servers-patterns/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 08:45:26 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[сеть]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=271</guid>
		<description><![CDATA[Нашел совершенно шикарнейший обзор методов написания высоконагруженных серверов в UNIX-подобных осях. Грамотно расписаны все плюсы, минусы и подводные камни. Есть еще даже более развернутая статья на ту же тему, но на английском.
]]></description>
			<content:encoded><![CDATA[<p>Нашел совершенно шикарнейший <a href="http://groups.google.ru/group/fido7.ru.unix.prog/browse_thread/thread/2c67ac2d1ca9e491/b49d41d9f713a284?pli=1" target="_blank">обзор методов написания высоконагруженных серверов</a> в UNIX-подобных осях. Грамотно расписаны все плюсы, минусы и подводные камни. Есть еще даже <a href="http://www.kegel.com/c10k.html" target="_blank">более развернутая статья</a> на ту же тему, но на английском.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/highload-servers-patterns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Duff’s Device</title>
		<link>http://typedef.ru/2009/09/duffs-device/</link>
		<comments>http://typedef.ru/2009/09/duffs-device/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 19:09:04 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[история]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=260</guid>
		<description><![CDATA[9 ноября 1983 года Том Дафф изобрел «устройство» имени себя. Вот так оно выглядело:

send&#40;to, from, count&#41;
	register short *to, *from;
	register count;
	&#123;
		register n=&#40;count+7&#41;/8;
		switch&#40;count%8&#41;&#123;
		case 0:	do&#123;	*to = *from++;
		case 7:		*to = *from++;
		case 6:		*to = *from++;
		case 5:		*to = *from++;
		case 4:		*to = *from++;
		case 3:		*to = *from++;
		case 2:		*to = *from++;
		case 1:		*to = *from++;
			&#125;while&#40;--n&#62;0&#41;;
		&#125;
	&#125;

Такая конструкция предназначалась для раскрутки цикла копирования фрагмента памяти в регистр [...]]]></description>
			<content:encoded><![CDATA[<p>9 ноября 1983 года Том Дафф изобрел «устройство» имени себя. Вот так оно выглядело:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">send<span style="color: #009900;">&#40;</span>to<span style="color: #339933;">,</span> from<span style="color: #339933;">,</span> count<span style="color: #009900;">&#41;</span>
	<span style="color: #993333;">register</span> <span style="color: #993333;">short</span> <span style="color: #339933;">*</span>to<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>from<span style="color: #339933;">;</span>
	<span style="color: #993333;">register</span> count<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #993333;">register</span> n<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span>count<span style="color: #339933;">+</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #0000dd;">8</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">switch</span><span style="color: #009900;">&#40;</span>count<span style="color: #339933;">%</span><span style="color:#800080;">8</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">:</span>	<span style="color: #b1b100;">do</span><span style="color: #009900;">&#123;</span>	<span style="color: #339933;">*</span>to <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>from<span style="color: #339933;">++;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">7</span><span style="color: #339933;">:</span>		<span style="color: #339933;">*</span>to <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>from<span style="color: #339933;">++;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">6</span><span style="color: #339933;">:</span>		<span style="color: #339933;">*</span>to <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>from<span style="color: #339933;">++;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">5</span><span style="color: #339933;">:</span>		<span style="color: #339933;">*</span>to <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>from<span style="color: #339933;">++;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">:</span>		<span style="color: #339933;">*</span>to <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>from<span style="color: #339933;">++;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">:</span>		<span style="color: #339933;">*</span>to <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>from<span style="color: #339933;">++;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">:</span>		<span style="color: #339933;">*</span>to <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>from<span style="color: #339933;">++;</span>
		<span style="color: #b1b100;">case</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">:</span>		<span style="color: #339933;">*</span>to <span style="color: #339933;">=</span> <span style="color: #339933;">*</span>from<span style="color: #339933;">++;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">--</span>n<span style="color: #339933;">&gt;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Такая конструкция предназначалась для <a href="http://en.wikipedia.org/wiki/Loop_unwinding" target="_blank">раскрутки цикла</a> копирования фрагмента памяти в регистр пословно. Развертывание сокращает количество итераций цикла и, как следствие, количество операций сравнения (в данном случае в 8 раз), тем самым слегка повышая производительность.</p>
<p>Чтобы лучше понять, что происходит, предлагаю читателям запустить следующую программу (я немного изменил изначальный вариант):</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include </span>
&nbsp;
<span style="color: #993333;">int</span> c <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> a <span style="color: #339933;">=</span> <span style="color: #0000dd;">10</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">void</span> foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d &quot;</span><span style="color: #339933;">,</span> c<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> bar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> a<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>a<span style="color: #339933;">&amp;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">:</span> <span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span> foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> bar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">:</span>      foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> bar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">:</span>      foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> bar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">:</span>      foo<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> bar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	       <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>a <span style="color: #339933;">-=</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Самое удивительное в этом всем — вовсе не корявое «столбчатое» форматирование. Удивительно то, что язык позволяет размещать <em>цикл внутри блока switch</em>. Интуитивно нам кажется, что каждый case начинает новый блок, и что нельзя соорудить блок, заключающий в себя несколько case&#8217;ов. А приведенный выше пример вообще представляется надругательством над синтаксисом C и здравым смыслом. Но стоит задуматься о том, как именно реализована конструкция switch-case, как сразу все становится на свои места:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// исходный код</span>
<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>a<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">:</span>
        a<span style="color: #339933;">++;</span>
        <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">:</span>
        a<span style="color: #339933;">--;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// что происходит на самом деле (примерно)</span>
case_0<span style="color: #339933;">:</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>a <span style="color: #339933;">==</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">goto</span> case_1<span style="color: #339933;">;</span>
    a<span style="color: #339933;">++;</span>
    <span style="color: #b1b100;">goto</span> end<span style="color: #339933;">;</span>
case_1<span style="color: #339933;">:</span>
    a<span style="color: #339933;">--;</span>
end<span style="color: #339933;">:</span></pre></div></div>

<p>Вот так! Теперь понятно, что внутри конструкции switch можно развернуться от души, чем и не преминул воспользоваться Дафф.</p>
<p>Вынужден разочаровать любителей микрооптимизаций: подобное развертывание циклов выполняется современными компиляторами автоматически, и, скорее всего, намного эффективнее. Компилятор ведь может себе позволить не заботиться о чистоте кода. Так что устройство Даффа теперь интересно разве что любителям истории программирования (вроде меня).</p>
<p>Жаждущих подробностей отправляю к <a href="http://www.lysator.liu.se/c/duffs-device.html" target="_blank">оригинальному сообщению Даффа</a> и <a href="http://en.wikipedia.org/wiki/Duff%27s_device" target="_blank">статье в Википедии</a>.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/duffs-device/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Электронные библиотеки технических книг</title>
		<link>http://typedef.ru/2009/09/technical-ebooks/</link>
		<comments>http://typedef.ru/2009/09/technical-ebooks/#comments</comments>
		<pubDate>Sun, 06 Sep 2009 04:26:57 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[книги]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=255</guid>
		<description><![CDATA[Достал из закладок:

http://scintific.narod.ru/literature.htm — каталог научно-технических электронных библиотек (как русских, так и иностранных);
http://nehudlit.ru — нехудожественная библиотека;
http://www.eknigu.com — научно-техническая библиотека;
http://www.iakovlev.org/index.html —  некоторое количество книг и статей по Linux и программированию;
http://www.ebook3000.com — буржуйские книги, преимущественно компьютерной тематики;
http://www.netbks.com — научные и компьютерные книги, на английском;
http://www.freebookcentre.net — очень много книг, в основном по CS и программированию;
http://www.mccme.ru/free-books — свободно [...]]]></description>
			<content:encoded><![CDATA[<p>Достал из закладок:</p>
<ul>
<li><a href="http://scintific.narod.ru/literature.htm" target="_blank">http://scintific.narod.ru/literature.htm</a> — каталог научно-технических электронных библиотек (как русских, так и иностранных);</li>
<li><a href="http://nehudlit.ru" target="_blank">http://nehudlit.ru</a> — нехудожественная библиотека;</li>
<li><a href="http://www.eknigu.com">http://www.eknigu.com</a> — научно-техническая библиотека;</li>
<li><a href="http://www.iakovlev.org/index.html" target="_blank">http://www.iakovlev.org/index.html</a> —  некоторое количество книг и статей по Linux и программированию;</li>
<li><a href="http://www.ebook3000.com" target="_blank">http://www.ebook3000.com</a> — буржуйские книги, преимущественно компьютерной тематики;</li>
<li><a href="http://www.ebook3000.com" target="_blank">http://www.netbks.com</a> — научные и компьютерные книги, на английском;</li>
<li><a href="http://www.freebookcentre.net" target="_blank">http://www.freebookcentre.net</a> — очень много книг, в основном по CS и программированию;</li>
<li><a href="http://www.mccme.ru/free-books" target="_blank">http://www.mccme.ru/free-books</a> — свободно распространяемые книги по математике.</li>
</ul>
<p>А откуда вы берете книги?</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/technical-ebooks/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Цикл в Makefile</title>
		<link>http://typedef.ru/2009/09/makefile-loop/</link>
		<comments>http://typedef.ru/2009/09/makefile-loop/#comments</comments>
		<pubDate>Sat, 05 Sep 2009 05:13:54 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[инструменты]]></category>
		<category><![CDATA[сборка]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=249</guid>
		<description><![CDATA[Возникла у меня такая задача: в действиях одной из целей Makefile выбрать из каталога файлы по маске *.eps и скормить их программе epstopdf. Проблема в том, что epstopdf принимает в командной строке только один файл. Нужен цикл. Я нашел два решения.
Первое — использовать шелловский for:

build:
    for epsfile in `ls *.eps`;\
   [...]]]></description>
			<content:encoded><![CDATA[<p>Возникла у меня такая задача: в действиях одной из целей Makefile выбрать из каталога файлы по маске *.eps и скормить их программе <code>epstopdf</code>. Проблема в том, что <code>epstopdf</code> принимает в командной строке только один файл. Нужен цикл. Я нашел два решения.</p>
<p>Первое — использовать шелловский <code>for</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="make" style="font-family:monospace;">build<span style="color: #004400;">:</span>
    for epsfile in `ls <span style="color: #004400;">*.</span>eps`<span style="color: #004400;">;</span>\
    do\
        epstopdf <span style="color: #000088; font-weight: bold;">$$</span>epsfile<span style="color: #004400;">;</span>\
    done</pre></div></div>

<p>Здесь две хитрости: экранирование концов строк (потому что <code>for</code> — фактически одна команда) и использование $$ перед именем переменной (потому что иначе она будет считаться макросом Make).</p>
<p>Второй способ использует возможности самого Make:</p>

<div class="wp_syntax"><div class="code"><pre class="make" style="font-family:monospace;"><span style="color: #004400;">%.</span>pdf<span style="color: #004400;">:</span> <span style="color: #004400;">%.</span>eps
    epstopdf <span style="color: #000088; font-weight: bold;">$?</span>
&nbsp;
build<span style="color: #004400;">:</span> <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #0000CC; font-weight: bold;">patsubst</span> <span style="color: #004400;">%.</span>eps<span style="color: #004400;">,</span> <span style="color: #004400;">%.</span>pdf<span style="color: #004400;">,</span> <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #0000CC; font-weight: bold;">wildcard</span> <span style="color: #004400;">*.</span>eps<span style="color: #004400;">&#41;</span><span style="color: #004400;">&#41;</span></pre></div></div>

<p>Такой подход имеет большое преимущество: теперь <code>epstopdf</code> не будет вызываться для EPS-файлов, которые не изменились с момента последнего вызова. К тому же это короче, хотя и, как мне кажется, хуже воспринимается визуально.</p>
<p>К сожалению, все это не удастся сократить до такого:</p>

<div class="wp_syntax"><div class="code"><pre class="make" style="font-family:monospace;">build<span style="color: #004400;">:</span> <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #0000CC; font-weight: bold;">wildcard</span> <span style="color: #004400;">*.</span>eps<span style="color: #004400;">&#41;</span>
    epstopdf <span style="color: #000088; font-weight: bold;">$?</span></pre></div></div>

<p>Здесь макрос $? развернется в строку, содержащую  имена сразу всех EPS-файлов, что противоречит условию.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/makefile-loop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plan 9: man emacs</title>
		<link>http://typedef.ru/2009/09/plan-9-man-emacs/</link>
		<comments>http://typedef.ru/2009/09/plan-9-man-emacs/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 05:47:33 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[юмор]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=244</guid>
		<description><![CDATA[Ржал в голос: http://cm.bell-labs.com/magic/man2html/1/emacs
Про vi тоже интересно.
]]></description>
			<content:encoded><![CDATA[<p>Ржал в голос: <a href="http://cm.bell-labs.com/magic/man2html/1/emacs" target="_blank">http://cm.bell-labs.com/magic/man2html/1/emacs</a></p>
<p>Про vi тоже интересно.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/plan-9-man-emacs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Проблемы с microtype и шрифтами</title>
		<link>http://typedef.ru/2009/09/microtype-fonts-problem/</link>
		<comments>http://typedef.ru/2009/09/microtype-fonts-problem/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 07:02:27 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[LaTeX]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[грабли]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=240</guid>
		<description><![CDATA[Я уже писал про одну из возможностей пакета microtype — висячую пунктуацию (кстати, это частный случай margin kerning — кернинга крайних символов в строке для визуального выравнивания границ текста). Так вот, этот пакет позволяет делать еще множество всяких микротипографских трюков (см. инструкцию). Один из основных — автоматическое растягивание шрифта (font expansion) для выравнивания пробелов между [...]]]></description>
			<content:encoded><![CDATA[<p>Я уже писал про одну из возможностей пакета <strong>microtype</strong> — <a href="http://typedef.ru/2008/12/latex-protrusion/" target="_blank">висячую пунктуацию</a> (кстати, это частный случай <em>margin kerning</em> — кернинга крайних символов в строке для визуального выравнивания границ текста). Так вот, этот пакет позволяет делать еще множество всяких микротипографских трюков (см. <a href="http://www.tex.ac.uk/tex-archive/macros/latex/contrib/microtype/microtype.pdf" target="_blank">инструкцию</a>). Один из основных — автоматическое растягивание шрифта (<em>font expansion</em>) для выравнивания пробелов между словами.</p>
<p>Не сказать чтобы мне это самое растягивание позарез как нужно, но после очередного обновления (у меня Fedora 11) моя статья перестала собираться, мотивируя это примерно так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ERROR: pdfTeX error <span style="color: #7a0874; font-weight: bold;">&#40;</span>font expansion<span style="color: #7a0874; font-weight: bold;">&#41;</span>: auto expansion is only possible with scalable fonts</pre></div></div>

<p>Это загнало меня в тупик на несколько часов. Конечно, Гугль знает о такой проблеме. И в инструкции к microtype все подробно написано. Ответ очевиден: использовать масштабируемый шрифт. Проблема только в том, что используемый по умолчанию шрифт <strong>cmr</strong> из пакета <strong>cm-super</strong> очень даже масштабируемый. Лог сборки по этому поводу тоже не особенно внятен.</p>
<p>Решение нашлось практически случайно. Некая загадочная редиска закомментировала в файле <strong>updmap.cfg</strong> строки, содержащие «cm-super». Мне достаточно было раскомментировать строку (я использую кодировку T2A):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">MixedMap cm-super-t2a.map</pre></div></div>

<p>и выполнить</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">sudo updmap</pre></div></div>

<p>Все заработало. За помощь в поимке редиски объявлено вознаграждение.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/microtype-fonts-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Планы на будущее</title>
		<link>http://typedef.ru/2009/09/plans/</link>
		<comments>http://typedef.ru/2009/09/plans/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 16:06:44 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[блог]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=237</guid>
		<description><![CDATA[Что-то я здорово забросил блог. Нехорошо. Конечно, этому была куча объективных причин. Работа, аспирантура, отпуск. Лень, наконец. Но главное — я никак не мог определиться с форматом. С одной стороны, хочется, чтобы каждый мой пост привносил в мир что-то разумное-доброе-вечное. Ну или хотя бы полезное. С другой стороны, чтобы написать что-то действительно полезное, как оказалось, [...]]]></description>
			<content:encoded><![CDATA[<p>Что-то я здорово забросил блог. Нехорошо. Конечно, этому была куча объективных причин. Работа, аспирантура, отпуск. Лень, наконец. Но главное — я никак не мог определиться с <em>форматом</em>. С одной стороны, хочется, чтобы каждый мой пост привносил в мир что-то разумное-доброе-вечное. Ну или хотя бы полезное. С другой стороны, чтобы написать что-то действительно полезное, как оказалось, нужна прямо-таки прорва времени. А учитывая более чем скромную посещаемость блога, тратить столько времени не хочется.</p>
<p>Посему я решил так. Писать буду чаще, но меньше. Буду выкладывать интересные ссылки, делиться приходящими в голову мыслями, больше писать о жизни «и вообще», но иногда публиковать и большие серьезные статьи. Например, у меня в черновиках лежат и ждут своей участи незаконченные посты:</p>
<ul>
<li>про формат ELF, его устройство и способы работы с ним;</li>
<li>краткое введение в Autotools;</li>
<li>плотная справочная статья про lex/flex;</li>
<li>философские задвиги по поводу обработки ошибок в C;</li>
<li>введение в Python;</li>
<li>и еще куча всякой мелочи.</li>
</ul>
<p>Все это я со временем приведу в порядок, проверю и опубликую. Не переключайтесь!</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/09/plans/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Оптические иллюзии</title>
		<link>http://typedef.ru/2009/06/optical-illusions/</link>
		<comments>http://typedef.ru/2009/06/optical-illusions/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 06:41:06 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=230</guid>
		<description><![CDATA[Очки с двумя японскими линзами стоят столько же, сколько не менее японский объектив SIGMA с четырнадцатью асферическими линзами, многослойным просветлением, переменным фокусным расстоянием и ультразвуковым мотором фокусировки.

]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Очки с двумя японскими линзами стоят столько же, сколько не менее японский объектив SIGMA с четырнадцатью асферическими линзами, многослойным просветлением, переменным фокусным расстоянием и ультразвуковым мотором фокусировки.</p>
<p style="text-align: justify;">Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/06/optical-illusions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Книга: «Ремесло программиста»</title>
		<link>http://typedef.ru/2009/06/kniga-remeslo-programmista/</link>
		<comments>http://typedef.ru/2009/06/kniga-remeslo-programmista/#comments</comments>
		<pubDate>Sun, 21 Jun 2009 10:06:42 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[книги]]></category>
		<category><![CDATA[методология]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=220</guid>
		<description><![CDATA[Название: Ремесло программиста: практика написания хорошего кода
Автор: Питер Гудлиф
Год выхода: 2009
Издательство: Символ-Плюс
Тираж: 1500
Объем: 704 стр.
Обложка: мягкая
Где покупал: books.ru
Цена: 690 р
Концентрированный программистский здравый смысл. Разбавлять водой по вкусу и употреблять ежедневно.
Жаль, что человеческий мозг устроен так, что не может сразу принять прочитанное на веру и закрепить на уровне рефлексов. Для подавляющего большинства начинающих программистов знания, изложенные [...]]]></description>
			<content:encoded><![CDATA[<p><strong><a title="Гудлиф П. Ремесло программиста" rel="lightbox[pics219]" href="http://typedef.ru/wp-content/uploads/2009/05/book-remeslo-goodliffe.jpg"><img class="attachment wp-att-196 alignleft" src="http://typedef.ru/wp-content/uploads/2009/05/book-remeslo-goodliffe.jpg" alt="Гудлиф П. Ремесло программиста" width="200" height="280" /></a>Название:</strong> Ремесло программиста: практика написания хорошего кода<br />
<strong>Автор:</strong> Питер Гудлиф<br />
<strong>Год выхода:</strong> 2009<br />
<strong>Издательство:</strong> Символ-Плюс<br />
<strong>Тираж:</strong> 1500<br />
<strong>Объем:</strong> 704 стр.<br />
<strong>Обложка:</strong> мягкая<br />
<strong>Где покупал:</strong> <a title="Ремесло программиста" href="http://www.books.ru/shop/books/634262" target="_blank">books.ru</a><br />
<strong>Цена:</strong> 690 р</p>
<p>Концентрированный программистский здравый смысл. Разбавлять водой по вкусу и употреблять ежедневно.</p>
<p>Жаль, что человеческий мозг устроен так, что не может сразу принять прочитанное на веру и закрепить на уровне рефлексов. Для подавляющего большинства начинающих программистов знания, изложенные в книге, являются абсолютно необходимыми. Это тот минимум, после которого человек имеет право называть себя программистом. Когда я учился программировать, таких книжек не было, поэтому все «золотые правила» приходилось открывать самостоятельно. Трудно сказать, какой путь лучше. В книге все разложено по полочками и проверено электроникой. С другой стороны, ничто так не способствует выработке правильных навыков, как хождение по граблям.</p>
<p>«Ремесло программиста» освещает почти все практические аспекты профессиональной разработки, и в этом здорово похожа на «Совершенный код» Макконнела. Но если последний претендует на некоторую всеобъемлющность (во словечко!), то Гудлиф пишет о более приземленных вещах, и делает это как-то более живенько. Читать интересно, местами даже забавно.</p>
<p><strong>Минусы:</strong></p>
<ul>
<li>картинки с обезьянами — дурацкие;</li>
<li>опытным программистам будет скучновато читать (хотя, пожалуй, так и должно быть).</li>
</ul>
<p><strong>Плюсы:</strong></p>
<ul>
<li>изложение систематическое, но при этом очень живенькое;</li>
<li>хороший перевод;</li>
<li>для лучшего запоминания в конце каждого раздела есть вопросы по прочитанному и вопросы для размышления; а в конце книги на вопросы еще и даются развернутые и обоснованные ответы;</li>
<li>для ленивых в тексте разбросаны «золотые правила», подводящие итог рассказанному на одной-двух предшествующих страницах.</li>
</ul>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/06/kniga-remeslo-programmista/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>О людях, мозгах и нежелании первых пользоваться вторым</title>
		<link>http://typedef.ru/2009/05/human-brains/</link>
		<comments>http://typedef.ru/2009/05/human-brains/#comments</comments>
		<pubDate>Sat, 30 May 2009 12:05:48 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=213</guid>
		<description><![CDATA[Меня всегда удивляет, когда люди тратят на что-то массу усилий и средств, но забывают подумать об одном небольшом, но очень важном аспекте, который может обесценить все затраты. Ну или значительную часть.
Ярчайший пример такого подхода (сначала потратить кучу денег, потом подумать) я каждый день наблюдаю по пути на работу. На станциях электричек и метро стоят турникеты. [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Меня всегда удивляет, когда люди тратят на что-то массу усилий и средств, но <strong>забывают подумать об одном небольшом, но очень важном аспекте, который может обесценить все затраты</strong>. Ну или значительную часть.</p>
<p style="text-align: justify;"><a title="Турникет-ветеран" rel="lightbox[pics213]" href="http://typedef.ru/wp-content/uploads/2009/05/broken_turniket.png"><img class="attachment wp-att-214 alignleft" src="http://typedef.ru/wp-content/uploads/2009/05/broken_turniket.thumbnail.png" alt="Турникет-ветеран" width="300" height="185" /></a>Ярчайший пример такого подхода (сначала потратить кучу денег, потом подумать) я каждый день наблюдаю по пути на работу. На станциях электричек и метро стоят турникеты. Казалось бы, простая задача с единственным условием: <strong>не пропускать человека, у которого нет билета</strong>.</p>
<p style="text-align: justify;">Проблема в том, что современные турникеты не выполняют основную свою функцию. Экономный народ массово преодолевает такие смешные для русского человека препятствия, не обращая даже внимания на дежурную тетеньку (смысл ее работы остается для меня загадкой). Без билета типичные турникеты с дверками можно преодолеть аж двумя способами.</p>
<ol style="text-align: justify;">
<li><strong>Пройти следом за пассажиром с билетом</strong>, прижавшись к нему якобы в порыве человеколюбия. Особенно этой уязвимости подвержены турникеты с двумя парами дверок: они не закрываются, пока не сработает сенсор «человек прошел». Ограничения на продолжительность открытия турникета, похоже, нет. Наверное, разработчики посчитали, что люди бывают разные, с большими животами и сумками. Или вдруг человек посреди турникета остановится и захочет постоять. Возникает же иногда такое желание — постоять в турникете. Правда ведь?<br />
В результате, зафиксированный мной рекорд — четыре человека прошли по одному билету гуськом.</li>
<li><strong>Перепрыгнуть</strong>. Тут все ясно, хотя в случае четырехдверчатых экземпляров не каждому это под силу. Видел всего несколько раз.</li>
</ol>
<p style="text-align: justify;">Когда первый способ прохода стал очевидным для железнодорожников, появились турникеты-триподы, с тремя трубами на одной оси (как в московских автобусах).</p>
<p style="text-align: justify;">О да, они не позволяют пройти гуськом (разве что двоим очень тощим). Зато с перепрыгиванием дело стало обстоять гораздо проще: преодолеть нужно всего лишь одну горизонтальную трубу. Но и это еще не все! Под таким турникетом легко <strong>подлезть</strong>! Какой удар для конструктора!</p>
<p style="text-align: justify;">Потратили, стало быть, кучу денег, а толку? Не беда — <em>денег еще много</em>! И у турникетов появились крепкие ребята в камуфляже. Народ насторожился. Не каждый теперь рискнет проскочить зайцем — шанс получить по почкам от правоохранителей перевешивал стоимость билета. Но хитрость скоро раскрылась. Крепкие ребята в камуфляже оказались <em>просто крепкими ребятами в камуфляже</em>. При попытке безбилетно преодолеть турникет они лишь устало бубнят: «По одному проходим, по одному». Все вернулось на круги своя. Средства потрачены, безработица среди крепких парней, тетенек и конструкторов турникетов стремительно упала, народ продолжает экономить. Все довольны.</p>
<p style="text-align: justify;">А ведь достаточно было подумать пару минут, чтобы устранить перечисленные выше «сравнительно законные способы» прохождения без билета. Например, при двух парах дверок не давать передней паре открываться, пока не закроется задняя (тут остается возможность перепрыгивания). Или вообще сделать как в Нью-Йоркском метро, «вертушку» высотой в человеческий рост. Конечно, у нас в стране порой задача «<em>сделать правильно</em>» как таковая не ставится, главное чтобы за эту работу можно было освоить деньги. Но это уже совсем другая история.</p>
<p style="text-align: justify;">Вопрос, как устранить возможность генерации фальшивых билетов на электричку, оставляется читателям в качестве несложной разминки для ума.</p>
<p style="text-align: justify;"><em>Надеюсь, вы не подумали, что этот пост про электрички и турникеты.</em></p>
<p style="text-align: justify;">Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/05/human-brains/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ворктрек, [подзад]пинарик</title>
		<link>http://typedef.ru/2009/05/worktrek-pinarik/</link>
		<comments>http://typedef.ru/2009/05/worktrek-pinarik/#comments</comments>
		<pubDate>Fri, 08 May 2009 11:17:34 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[инструменты]]></category>
		<category><![CDATA[продуктивность]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=197</guid>
		<description><![CDATA[Любителям посидеть в рабочее время на башоргах и ЖЖ посвящается. Изначальная идея «пинарика» была проста — наглядно продемонстрировать себе, что жизнь, мол, проходит мимо, пора бы уже что-нибудь существенное сделать. Закрашиваешь, закрашиваешь ячейки, и прям видишь, как на глазах сокращается отведенное тебе время.
Ворктрек — производная пинарика. В нем можно еще и пометить каждый день как [...]]]></description>
			<content:encoded><![CDATA[<p>Любителям посидеть в рабочее время на башоргах и ЖЖ посвящается. <a href="http://www.improvement.ru/zametki/pinarik/" target="_blank">Изначальная идея</a> «пинарика» была проста — наглядно продемонстрировать себе, что жизнь, мол, проходит мимо, пора бы уже что-нибудь существенное сделать. Закрашиваешь, закрашиваешь ячейки, и прям видишь, как на глазах сокращается отведенное тебе время.</p>
<p><a href="http://worktrek.com/" target="_blank">Ворктрек</a> — производная пинарика. В нем можно еще и пометить каждый день как продуктивный (зелененький) или непродуктивный (красненький). И еще комментарий приписать. Такая штука пинает уже серьезно, с двух ног. Подсознательный эффект поразителен: <strong>начинаешь сам с собой устраивать соревнования</strong>. Сколько я смогу подряд «зеленых» дней сделать? Слабо неделю без «красных»? Эстеты могут даже организовать свое рабочее время так, чтобы на картинке красными и зелеными клетками написалось какой-нибудь слово. Например, «труд». Или «мир».</p>
<p style="text-align: center;"><a title="Worktrek" rel="lightbox[pics197]" href="http://typedef.ru/wp-content/uploads/2009/05/worktrek.png"><img class="attachment wp-att-201 centered" src="http://typedef.ru/wp-content/uploads/2009/05/worktrek.png" alt="Worktrek" width="340" height="102" /></a></p>
<p>Интерфейс приятно минималистичен, но функционален. Конечно, многого не хватает (например, двух цветов все же маловато), но Ворктрек быстро развивается и, что особенно приятно, с учетом мнения пользователей. Что еще нужно хорошему инструменту? Пользуйтесь!</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/05/worktrek-pinarik/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Eclipse vs. Emacs</title>
		<link>http://typedef.ru/2009/05/eclipse-vs-emacs/</link>
		<comments>http://typedef.ru/2009/05/eclipse-vs-emacs/#comments</comments>
		<pubDate>Tue, 05 May 2009 11:20:23 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[инструменты]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=189</guid>
		<description><![CDATA[Без сомнения, Emacs — лучший текстовый редактор  из тех, что мне доводилось видеть. После некоторого периода адаптации и допила производительность труда возрастает фантастически. Но только если выполняются два условия:

работа выполняется с отдельными файлами, не объединенными в проект;
узким местом производительности является именно ввод или редактирование текста, а не мыслительный процесс.

Проблема в том, что в случае разработки [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Без сомнения, Emacs — лучший текстовый редактор  из тех, что мне доводилось видеть. После некоторого периода адаптации и допила производительность труда возрастает фантастически. Но только если выполняются два условия:</p>
<ol style="text-align: justify;">
<li>работа выполняется с отдельными файлами, не объединенными в проект;</li>
<li>узким местом производительности является именно ввод или редактирование текста, а не мыслительный процесс.</li>
</ol>
<p style="text-align: justify;">Проблема в том, что <strong>в случае разработки ПО не выполняются оба условия</strong>. Программы, компилируемые из одного файла с исходниками, остались где-то на первом курсе. А что касается второго — если вы придумываете код быстрее, чем можете его написать, значит вам определенно стоит больше думать над кодом. Например, моя лично производительность редко когда поднимается выше пятидесяти строк в час — я имею в виду полностью завершенный код, покрытый тестами, проверенный и снабженный комментариями. Каждая недодуманная минута сейчас оборачивается в дальнейшем часами головной боли при отладке. Так что я предпочитаю писать код медленно, но верно. Получается, не поверите, быстрее.</p>
<p style="text-align: justify;">С проектами в Emacs все ужасно. Особенно с программными проектами. Есть мощнейшие режимы и модули, призванные сделать из текстового редактора полноценную IDE — <strong>etags</strong>, <strong>semantic</strong>, <strong>ecb</strong>, <strong>cedet</strong>, <strong>ede</strong>&#8230; Масса возможностей, множество путей расширения и настройки, но&#8230; Довольно быстро понимаешь, что это напоминает попытку Linux пробиться на десктопы домохозяек. Разработчики пыжатся, пытаются реализовать функциональность «больших» IDE, «догнать и перегнать», но выходит, что все это не повышает производительность, а снижает ее.</p>
<p style="text-align: justify;">Я честно больше двух месяцев пытался настроить cedet и ecb под свои нужды, писал свои функции, часами рылся на емаксовых сайтах. Единственный положительный эффект — относительно неплохо выучил elisp, хотя многие сочтут это сомнительным достижением. Короче говоря, <strong>для проектов Emacs непригоден</strong>.</p>
<p style="text-align: justify;">Поэтому я вернулся в Eclipse. И вскоре обнаружил там вот такое:</p>
<p style="text-align: justify;">
<p style="text-align: center;"><a title="Eclipse Keys Preferences" rel="lightbox[pics189]" href="http://typedef.ru/wp-content/uploads/2009/05/eclipse-emacs.png"><img class="attachment wp-att-191 centered" src="http://typedef.ru/wp-content/uploads/2009/05/eclipse-emacs.thumbnail.png" alt="Eclipse Keys Preferences" width="400" height="288" /></a></p>
<p style="text-align: justify;">И правда, привязка базовых операций как в Emacs! Но моя радость была недолгой: мозг решительно воспротивился использованию привычных, казалось бы, комбинаций, в «некошерной» IDE. Я постоянно нажимал не туда, портил исходники, плевался и ругался. Кроме того, все мои любовно написанные elisp-функции и нестандартные привязки, понятное дело, в Eclipse не перетащишь. Поэтому я вернул все на место.</p>
<p style="text-align: justify;">Теперь работаю в Eclipse. Комфорт разработки заметно вырос.</p>
<p style="text-align: justify;">Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/05/eclipse-vs-emacs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Книга: «Научные исследования»</title>
		<link>http://typedef.ru/2009/05/book-nauchnye-issledovaniya/</link>
		<comments>http://typedef.ru/2009/05/book-nauchnye-issledovaniya/#comments</comments>
		<pubDate>Fri, 01 May 2009 09:56:45 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[книги]]></category>
		<category><![CDATA[наука]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=179</guid>
		<description><![CDATA[Новый формат постов — описания книг. Буду описывать здесь все книги, хоть как-то связанные с тематикой блога, которые мне довелось прочитать. С конкретно этой начну просто потому, что только что ее закончил; может быть, потом опишу кое-что из уже давно прочитанного. Думаю, я также буду где-нибудь на боковой панели отображать книгу, которую я в настоящий [...]]]></description>
			<content:encoded><![CDATA[<p>Новый формат постов — описания книг. Буду описывать здесь все книги, хоть как-то связанные с тематикой блога, которые мне довелось прочитать. С конкретно этой начну просто потому, что только что ее закончил; может быть, потом опишу кое-что из уже давно прочитанного. Думаю, я также буду где-нибудь на боковой панели отображать книгу, которую я в настоящий момент читаю и обзор которой затем появится здесь. В общем, «откиньтесь на спинку кресла» и пишите отзывы, стоит ли мне продолжать.</p>
<p><strong><a title="Ворона, Тихонов: Научные исследования" rel="lightbox[pics179]" href="http://typedef.ru/wp-content/uploads/2009/05/vorona-issled1.jpg"><img class="attachment wp-att-183 alignleft" src="http://typedef.ru/wp-content/uploads/2009/05/vorona-issled1.thumbnail.jpg" alt="Ворона, Тихонов: Научные исследования" width="199" height="280" /></a>Название:</strong> Научные исследования: концептуальные, теоретические и практические аспекты<br />
<strong>Авторы:</strong> Тихонов В. А. и Ворона В. А.<br />
<strong>Год выхода:</strong> 2009<br />
<strong>Издательство:</strong> Горячая линия — телеком<br />
<strong>Тираж:</strong> 1000<br />
<strong>Объем:</strong> 296 стр.<br />
<strong>Обложка:</strong> мягкая<br />
<strong>Где покупал:</strong> <a title="Научные исследования" href="http://www.books.ru/shop/books/644858" target="_blank">books.ru</a><br />
<strong>Цена:</strong> 271 р</p>
<p>Методическое пособие для чайников-аспирантов. Я очень жалею, что такая книга не попалась мне, когда я писал магистерский диссер, потому что в ней как раз приведены ответы на вопросы, от которых мой научный руководитель старательно увиливал.</p>
<p>Как отличить исследование от не-исследования? Является ли некоторое исследование научным? Что должно входить в исследование, в какой последовательности нужно его выполнять, как оформлять результаты работы? Какие разделы должны входить в диссертацию и что в этих разделах писать? Как придумать название темы? Чем отличаются тема, объект, предмет, задачи и цели исследования? На все эти вопросы в книге приводятся более или менее ясные ответы.</p>
<p>Книгу мне привез курьер в институт, и когда я поднимался на лифте, встретился с сотрудницей отдела аспирантуры. Углядела она у меня эту книжку, и тут же отобрала. Вечером, правда, вернула. Но с условием, чтобы я еще две книжки заказал для общественного пользования. Потом с подачи отдела аспирантуры еще два человека ко мне пришли и попросили заказать. В общем, пиар-акция удалась на славу. А тираж-то небольшой&#8230;</p>
<p>В целом книжка неплохая, рекомендую. Но если у вас есть знакомые-аспиранты, вполне хватит одной на всех — перечитывать ее несколько раз вряд ли стоит.</p>
<p><strong>Минусы:</strong></p>
<ul>
<li>похожа на лоскутное одеяло: фрагменты книги явно писались разными авторами и в разное время (в том числе советское); встречается куча архаизмов («кибернетика», «вскрыть зависимости»); есть даже ссылки на Маркса и Энгельса;</li>
<li>некоторые части совершенно в духе «космических кораблей, бороздящих просторы вселенной»; много воды; сделать бы книгу раза в четыре меньше — цены бы ей не было;</li>
<li>верстка так себе, шрифт не очень приятен для глаз; много опечаток, пропущенных слов и несогласованных падежей;</li>
<li>непонятно, зачем нужен материал про докторские диссертации; докторанты все изложенное и так уже должны знать;</li>
<li>в середине книги обнаружен рекламный лист, причем не вложенный, а переплетенный вместе с остальными (убило наповал).</li>
</ul>
<p><strong>Плюсы:</strong></p>
<ul>
<li>многие фрагменты потрясающе лаконичные и насыщенные;</li>
<li>книга разжевывает основные проблемы, до решения которых аспирантам (да и дипломникам) приходится доходить ценой многих усилий и шишек.</li>
</ul>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/05/book-nauchnye-issledovaniya/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Logitech MX Revolution и Linux: как достичь счастья</title>
		<link>http://typedef.ru/2009/04/logitech-mx-revolution-and-linux-how-to-reach-happiness/</link>
		<comments>http://typedef.ru/2009/04/logitech-mx-revolution-and-linux-how-to-reach-happiness/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 19:06:44 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[железо]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=174</guid>
		<description><![CDATA[Беспроводную красавицу мне подарили на день рождения. Она была приятна на ощупь, обладала потрясающей функциональностью и комфортом, долго держала заряд. Но, как это нередко случается с красавицами, обладала скверным характером, и до ее сердца достучаться было непросто.
Тогда основной моей осью была Windows 2003 Server. Удобная и надежная система, под которую драйверы и серьезные программы отказывались [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.logitech.com/index.cfm/mice_pointers/mice/devices/130&amp;cl=ru,ru" target="_blank">Беспроводную красавицу</a> мне подарили на день рождения. Она была приятна на ощупь, обладала потрясающей функциональностью и комфортом, долго держала заряд. Но, как это нередко случается с красавицами, обладала скверным характером, и до ее сердца достучаться было непросто.</p>
<p>Тогда основной моей осью была Windows 2003 Server. Удобная и надежная система, под которую драйверы и серьезные программы отказывались ставиться буквально через одного. Мол, у вас серверная ОС, мы вас боимся. Вдруг к нам придет ваш бородатый админ и будет ругаться? И вообще, купите лучше серверную версию нашего продукта втрое дороже. Или поставьте XP. Или пойдите еще куда-нибудь. Запуск установщика в режиме эмуляции XP иногда помогал, но чаще — нет. Это несколько напрягало, но обычно нужным программам находились альтернативы. С драйверами сложнее.</p>
<p>Вот и когда я распаковал шедевр коробочного искусства и извлек оттуда пресловутый космический девайс, со всей остротой встал вопрос — как заставить работать все эти 11 кнопок и 1 колесико? Фирменный <a href="http://www.logitech.com/index.cfm/428/130&amp;cl=ru,ru?softwareid=671&amp;osid=1" target="_blank">SetPoint</a>, увидев серверную винду, прикинулся шлангом, и припарки не помогли. Альтернатив этому поделию не предусмотрено. Впрочем, со временем я эту проблему решил (если кому будет интересно, расскажу как).</p>
<p>Затем я перешел на Linux. Собственно, я и не ожидал, что моя MX Revo будет нормально там работать. Две кнопки и колесико — что еще нужно настоящему программисту? Но Fedora 10 далеко превзошла мои ожидания, автоматически и правильно опознав 8 кнопок из 11. Единственное, что меня расстраивало — невозможность использовать вместо нажатия на центральное колесико нажатие на боковое псевдо-колесико (нажатие на центральное колесико у меня меняет режим вращения). Удобно, знаете ли, ссылки в Firefox открывать и вкладки закрывать.</p>
<p>Итак, я хотел, <strong>чтобы нажатие на боковое колесико имело тот же эффект, что и нажатие на вторую кнопку мыши</strong> (основное колесико у большинства смертных). После вознесения правильной молитвы Гуглу, нашлось <a href="http://www.howtoforge.com/logitech_mx_revolution_mousebuttons_fedora7" target="_blank">решение</a>. Подробно описывать не буду — там и так все понятно. Решение прекрасное, но у него есть один недостаток — оно не работает. Точнее, в моем случае не работает.</p>
<p>С помощью <a href="http://hocwp.free.fr/xbindkeys/xbindkeys.html" target="_blank">xbindkeys</a>, действительно, можно сопоставить команде оболочки некоторые нажатия мышиных и клавиатурных кнопок. Осталась самая малость — соответствующей командой оболочки <strong>сэмулировать нажатие второй кнопки мыши</strong>. Если верить документации на <a href="http://homepage3.nifty.com/tsato/xvkbd/" target="_blank">xvkbd</a>, то это можно сделать так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#~/.xbindkeysrc</span>
<span style="color: #ff0000;">&quot;/usr/bin/xvkbd -xsendevent -text &quot;</span>\m2<span style="color: #ff0000;">&quot;&quot;</span>
b:<span style="color: #000000;">17</span></pre></div></div>

<p>Проблема в том, что <code>xvkbd</code> не желает эмулировать мышиные клики. Что ж, незаменимых у нас нет. После непродолжительных поисков нахожу <a href="http://www.semicomplete.com/projects/xdotool/xdotool" target="_blank">xdotool</a>. Проверяю вручную, набрав в консоли:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">xdotool click <span style="color: #000000;">2</span></pre></div></div>

<p>Действительно, нажатие второй кнопки происходит. Теперь меняем <code>~/.xbindkeysrc</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#~/.xbindkeysrc</span>
<span style="color: #ff0000;">&quot;~/bin/xdotool click 2&quot;</span>
b:<span style="color: #000000;">17</span></pre></div></div>

<p>Запустив <code>xbindkeys</code> в режиме отладки (ключ <code>-v</code>), вижу, что при нажатии на 17-ю кнопку (то самое псевдоколесико) действительно происходит эмуляция нажатия на 2-ю. Но видимого эффекта почему-то нет. Мистика. Подумав немного, решаю, что <code>xdotool</code> конфликтует c <code>xbindkeys</code>. Решение очевидно: <em>разнести их по времени</em>.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#~/.xbindkeysrc</span>
<span style="color: #ff0000;">&quot;sleep 0.15; ~/bin/xdotool click 2&quot;</span>
b:<span style="color: #000000;">17</span></pre></div></div>

<p>Работает! Величина задержки подбирается экспериментально. У меня при 0.1 все еще есть конфликт, а при 0.15 — работает. Такая маленькая задержка практически не заметна, и неудобств не доставляет.</p>
<p>Ну, а как сменить кнопку, по которой переключается режим работы колесика, давно уже <a href="http://habrahabr.ru/blogs/linux/39129/" target="_blank">написали на Хабре</a>.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/04/logitech-mx-revolution-and-linux-how-to-reach-happiness/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Как не надо ремонтировать жесткий диск</title>
		<link>http://typedef.ru/2009/04/how-shouldnt-repair-hdd/</link>
		<comments>http://typedef.ru/2009/04/how-shouldnt-repair-hdd/#comments</comments>
		<pubDate>Fri, 03 Apr 2009 19:49:19 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[грабли]]></category>
		<category><![CDATA[железо]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=170</guid>
		<description><![CDATA[История со мной произошла пренеприятнейшая, но со счастливым концом и мощным назидательным содержанием.
Есть такие люди, которые идут-идут своей тропинкой, посматривают по сторонам, и вдруг — бац! Наступают на грабли. Другие заранее замечают разложенный на дороге коварный садовый инвентарь, и обходят опасное место кустиками. Мой случай более интересен — я наступил в метафорическую кучу дерьма. И [...]]]></description>
			<content:encoded><![CDATA[<p>История со мной произошла пренеприятнейшая, но со счастливым концом и мощным назидательным содержанием.</p>
<p>Есть такие люди, которые идут-идут своей тропинкой, посматривают по сторонам, и вдруг — бац! Наступают на грабли. Другие заранее замечают разложенный на дороге коварный садовый инвентарь, и обходят опасное место кустиками. Мой случай более интересен — я наступил в метафорическую кучу дерьма. И вместо того, чтобы обтереть ботинок листиком, я поперся в бурелом на поиски крана с водой, и уже там наступил на свои грабли. Причем несколько раз.</p>
<p>Кого интересовала философская сторона вопроса, могут дальше не читать. А я все же приведу немного подробностей.</p>
<p>Компьютер внезапно перестал грузиться. Проходит POST, появляется надпись о попытке загрузить с CD — и тишина. Ни сообщений, ни воплей спикера — ничего. Ну, думаю, первичный загрузчик накрылся. Мелькнула у меня мысль вроде «А с чего бы он вдруг вот так взял и накрылся?», но симптомы были слишком очевидны. Достал с дальней полки установочный диск древней Slackware, загрузился. Смотрю — диск целый, таблица разделов в сохранности, сами разделы монтируются, fsck не ругается. Мистика просто: кто-то взял, и аккуратно так испортил начало MBR.</p>
<p>Ладно, зря что ли я писал свой загрузчик? Нахожу GRUB, командую ему «фас», он послушно пишет первую ступень в MBR. Перезагрузка. Тишина. Повторяем с другими настройками. То же самое. Через 20 минут я начинаю тихо закипать. Скачал Live CD Fedora 10 с ноутбука, может дело в версии GRUB?.. То же самое.</p>
<p>Тут вспоминаю, что вроде бы я делал бэкап первого сектора. Лезу в недра домашнего каталога — вот он, голубчик! Вооружившись dd, лихим кавалерийским наскоком переписываю резервную копию на диск. И когда уже палец опускался на Enter, я вспоминаю, что <em>бэкап-то был от другого диска</em>&#8230; Но поздно. Таблица разделов безвозвратно утеряна. Диск превратился в груду бессмысленных секторов.</p>
<p>Но не все потеряно! Есть же <a href="http://www.brzitwa.de/mb/gpart/index.html" target="_blank">gpart</a> — моя последняя надежда! Запускаю его на полное сканирование, вижу как он успешно находит раздел NTFS и со спокойной душой иду спать — работать он будет (по опыту) долго. Утром gpart показывает кашу из незнакомых мне разделов. «<em>Не шмогла</em>». Иду гуглить. Оказывается, есть еще одна подобная утилита &#8211; <a href="http://www.cgsecurity.org/wiki/TestDisk" target="_blank">testdisk</a>. Ставлю ее, запускаю сканирование. От силы через две секунды (!) она мне выдает правильный список разделов. Фууф, гора с плеч. Save. GRUB. Перезагрузка. Опять тишина&#8230;</p>
<p>Вдумчивый читатель, наверное, уже догадался, чем окончилась моя история. Я наконец-то зашел в настройки BIOS и увидел, что <em>сбился порядок загрузки с носителей</em>. Компьютер все время пытался грузиться с диска, на котором загрузчика просто не было. А от моих манипуляций с другим диском, разумеется, ничего не менялось.</p>
<p>Вот такая история. А мораль простая — надо чаще думать головой.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/04/how-shouldnt-repair-hdd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Наука? Какая такая наука?</title>
		<link>http://typedef.ru/2009/04/science-what-science/</link>
		<comments>http://typedef.ru/2009/04/science-what-science/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 10:52:34 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[наука]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=160</guid>
		<description><![CDATA[Почему в США (например) гордятся своей наукой, а у нас ее пинают все кому не лень? Иногда, знаете ли, под настроение прочитаешь статейку-другую про то, как у нас все плохо, выдавишь скупую мужскую слезу&#8230; И этакое настроение возникает печально-ностальгическое, мол, в СССР вон какая научища была, а сейчас все испортили, все разворовали. Выйдешь на улицу, [...]]]></description>
			<content:encoded><![CDATA[<p>Почему в США (например) гордятся своей наукой, а у нас ее пинают все кому не лень? Иногда, знаете ли, под настроение прочитаешь статейку-другую про то, как у нас все плохо, выдавишь скупую мужскую слезу&#8230; И этакое настроение возникает печально-ностальгическое, мол, в СССР вон какая научища была, а сейчас все испортили, все разворовали. Выйдешь на улицу, сядешь на лавочку возле подъезда — и есть что обсудить с товарищами. Вот только делать никто ничего не будет, и ничего не изменится. В этом все проявляют завидное согласие.</p>
<p>Между тем, изменения к лучшему в отечественной науке возможны. Даже с таким мизерным бюджетом и катастрофически упавшим уровнем образования. Просто <strong>правильные люди должны задать себе правильные вопросы</strong>, и постараться честно на них ответить. Глядишь, и мысли какие-нибудь на ум придут.</p>
<p>Попробую со своей скромной колокольни сформулировать несколько вопросов, на мой взгляд, совершенно критичных для современной науки, причем не только в России. В порыве графоманства приведу еще и ответы на эти вопросы как бы «с той стороны».</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>Что характеризует успешность ученого?</em></p>
<p><span style="color: #800000;"><strong>Ответ</strong></span>. Ну очевидно же, успешность ученого характеризуется успешностью его работ. Если он опубликовал свою работу, и другие ученые сочли ее интересной и оригинальной, опираются на нее в своих исследованиях, то работу можно считать успешной. Вроде даже какой-то термин был&#8230; А, во, «<em>индекс цитирования</em>»!</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>А что насчет научной степени? Она является показателем успешности?</em></p>
<p><strong><span style="color: #800000;">Ответ</span></strong>. Разумеется! Если человек получил степень, он ведь уже совершил какую-то серьезную научную работу, правильно? Хотя нет, постойте&#8230; При защите же нет требований к индексу цитирования, значит, успешность работы во внимание не принимается. А значит&#8230; Значит, оценивается просто способность человека написать хоть какую-нибудь научную работу. Выходит, процесс получения степени — это просто способ отфильтровать людей, в принципе не способных к науке!</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>Почему существют фирмы, пишущие диссертации за деньги?</em></p>
<p><span style="color: #800000;"><strong>Ответ</strong></span>. Потому что существует спрос на диссертации. Видимо, преимущества от получения степени достаточно велики, чтобы за них платить. Хотя это странно, конечно, — защищать диссертацию, если не можешь написать ее сам. Это ведь фильтр, а сама научная работа начинается только после защиты&#8230; Наверное, дело в самом по себе статусе научной степени. Но какой толк от такого статуса, если степень ничего не говорит об успешности?.. Брр, парадокс какой-то.</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>Какие стимулы у научного руководителя выпускать кандидатов с качественными работами и не выпускать с некачественными?</em></p>
<p><span style="color: #800000;"><strong>Ответ</strong></span>. Эээ. Не знаю. Видимо, никаких.</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>Зачем нужны ВАКовские журналы?</em></p>
<p><span style="color: #800000;"><strong>Ответ</strong></span>. Это журналы, публикации в которых означают признание работы официальным научным сообществом. А, нет, признание отражает индекс цитирования. Стало быть, ВАКовская публикация ничем не отличается от обычной, кроме официального статуса. Для получения степени необходимо иметь публикации в ВАКовских журналах. Я бы даже сказал, что таких публикаций в этих журналах большинство. Черт, выходит, что в ВАКовских журналах публикуются менее качественные работы. Что-то вы совсем мне голову задурили!</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>Есть ли у ученых мотивация делать качественные работы? Они находят свое применение?</em></p>
<p><span style="color: #800000;"><strong>Ответ</strong></span>. Сами знаете, в каком положении сейчас промышленность. Результаты практических исследований практически не внедряются — нет ни воли руководства, ни средств. Насчет фундаментальных и так понятно. Фактически, исследования ведутся или ради получения грантов, или просто из интереса. Что касается рядовых ученых, то до них и гранты редко доходят, остается только увлечение наукой.</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>Зачем нужна Академия наук? Какую роль играют академики и член-корреспонденты?</em></p>
<p><span style="color: #800000;"><strong>Ответ</strong></span>. По идее, РАН должна управлять распределением средств между перспективными разработками. Перспективность ведь могут оценить только ученые, правильно? А академики и членкоры — это как раз заслуженные ученые, которым доверено делать правильный выбор.</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>То есть любой ученый, даже самый молодой, может расчитывать на получение средств, если его исследование представляет ценность?</em></p>
<p><span style="color: #800000;"><strong>Ответ</strong></span>. Теоретически да, но на практике большую роль играют личные связи. В основном деньги получают крупные ученые и руководители институтов. Молодому ученому приходится или пробиваться «наверх», начиная с рядового сотрудника какого-нибудь НИИ, или же обзаводиться нужными связями как-то еще. Через политику, например.</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>Зачем аспиранты изучают философию науки?</em></p>
<p><span style="color: #800000;"><strong>Ответ</strong></span>. Нуу&#8230; Эээ&#8230; Нужно же преподавателям философии на что-то жить :)</p>
<p><span style="color: #008000;"><strong>Вопрос</strong></span>. <em>А что вы лично сделали для науки?</em></p>
<p><span style="color: #800000;"><strong>Ответ</strong></span>. (в ужасе убегает)</p>
<p>Думаю, моя идея понятна. Список вопросов легко можно продолжать до бесконечности. В России главная, на мой взгляд, проблема — нежелание задавать себе вопросы и давать на них честные ответы. В результате получается, что власть вопит «<em>Спасем молодых ученых! Спасем науку!</em>», пилят под это дело астрономические бюджеты, а потом удивляются — как же так, почему все так плохо, мы же столько всего сделали! А «снизу» картина выглядит как непрекращающийся театр абсурда, в котором мы вынуждены принимать участие.</p>
<p>Когда у ученых нет стимула качественно делать свою работу и дорожить своим именем, когда результаты исследований никому не нужны, когда получение степени заключается в способности не сойти с ума в бюрократической волоките и когда в научных журналах публикуются «для галочки» — стоит ли ожидать, что вдруг все станет лучше?</p>
<p>Ух, как я патетично завернул. Надо закончить более позитивно. Коллеги, я знаю что делать! <strong>Работать надо, а не делать вид!</strong> В науке есть только два принципа: самоценность истины и установка на создание нового знания. А звания, степени и прочая бюрократия — это все мишура.</p>
<p><strong>Ссылки по теме:</strong></p>
<p><a href="http://rsdn.ru/forum/message/3350093.flat.aspx#3350093" target="_blank">Почему у нас такая наука (RSDN)</a><a href="http://www.inauka.ru/science/article35185/print.html" target="_blank"><br />
В чем заключались достоинства и недостатки советской науки</a><a href="http://www.informika.ru/text/magaz/newpaper/messedu/cour9912/1900.html" target="_blank"><br />
Зачем нам корова?<br />
</a><a href="http://www.ras.ru/digest/fdigestlist/bulletin.aspx" target="_blank">Бюллетень в защиту науки</a></p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/04/science-what-science/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TDD и модульные тесты: нужны ли они?</title>
		<link>http://typedef.ru/2009/02/tdd-unit-tests/</link>
		<comments>http://typedef.ru/2009/02/tdd-unit-tests/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 10:20:03 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[методология]]></category>
		<category><![CDATA[тестирование]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=145</guid>
		<description><![CDATA[Интернет-блоггинг дает каждому свободу самовыражения, возможность высказать свое мнение и быть услышанным. Так иногда говорят. На деле оказывается, что существует некоторое (небольшое) число популярных людей, которые создают первоначальную информацию. Остальные блоггеры моментально подхватывают знамя, и по сети, как круги на воде, распространяется волна вторичных и пятидясетиричных производных. Инициирующий пост может быть совершенно бессодержательным, глупым и [...]]]></description>
			<content:encoded><![CDATA[<p>Интернет-блоггинг дает каждому свободу самовыражения, возможность высказать свое мнение и быть услышанным. Так иногда говорят. На деле оказывается, что существует некоторое (небольшое) число популярных людей, которые создают первоначальную информацию. Остальные блоггеры моментально подхватывают знамя, и по сети, как круги на воде, распространяется волна вторичных и пятидясетиричных производных. Инициирующий пост может быть совершенно бессодержательным, глупым и никому не нужным, но порождаемый им поток обсуждений иногда может привести к чему-то новому и полезному.</p>
<p>В программерской блогосфере таких «первичных» людей немало, особенно если принимать во внимание англоязычные блоги. Но самый знаменитый, как ни крути, <a title="Joel on Software" href="http://www.joelonsoftware.com" target="_blank">Джоэль Спольски</a>. Знаменит он в основном тем, что увлекательно пишет о банальных вещах, издает по мотивам блога <a title="Джоэль о программировании" href="http://www.books.ru/shop/books/419540" target="_blank">книги</a>, и тем, что его блог предопределил успех его софтверной компании <a title="Fog Creek Software" href="http://fogcreek.com/" target="_blank">Fog Creek</a>. Он не обязательно пишет все правильно и обстоятельно, но зато читать его интересно, и это вдохновляет никому неизвестного блоггера написать «<em>вот Джоэль вчера написал то-то, а я по этому поводу думаю вот это</em>», после чего следует шикарнейший узкоспециальный пост.</p>
<p>Я не склонен к паразитированию на популярных трендах, но мимо этой мощной волны я просто не мог пройти мимо, поскольку был искренне возмущен.</p>
<p>Началось все с <a title="StackOverflow: podcast 38" href="http://blog.stackoverflow.com/2009/01/podcast-38/" target="_blank">подкаста номер 38 на StackOverflow</a>, в котором Джоэль и <a title="Coding Horror" href="http://www.codinghorror.com/blog/" target="_blank">Джефф Этвуд</a> диалогируют на разнообразные IT-темы. В частности, они затрагивают вопрос юнит-тестов и методологии TDD; это вызвало такую бурную дискуссию, что Джоэль аж написал <a title="From Podcast 38" href="http://www.joelonsoftware.com/items/2009/01/31.html" target="_blank">целый пост</a>, приведя там стенограмму оного фрагмента подкаста. Вкратце, ключевые мысли примерно такие:</p>
<ol>
<li><em>TDD — бесполезная штука, потому что 100% покрытие кода тестами очень тяжело достичь, да и не нужно.</em></li>
<li><em>Модульные тесты не нужны, потому что на них тратится слишком много времени. Кроме того, если что-то нужно будет менять в коде, возможно придется изменить кучу тестов.</em></li>
<li><em>Писать тесты для унаследованного кода тяжело и ненужно (и поэтому модульные тесты вообще не нужны).</em></li>
</ol>
<p>Я, конечно, несколько преувеличил. Но не одному мне это показалось ересью. <a title="Uncle Bob" href="http://blog.objectmentor.com/articles/2009/01/31/quality-doesnt-matter-that-much-jeff-and-joel" target="_blank">Разгромный отзыв</a> написал Uncle Bob (автор agile-подхода и <a title="Principles of OOD" href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod" target="_blank">принципов SOLID</a>, по которым Джоэль тоже проехался), пожурив авторов с этакой отцовской грустью («<em>Джоэль, ты неправ</em>») и усомнившись в целесообразности использования разрабатываемых ими продуктов. Маленькую <a title="Kent Beck" href="http://www.threeriversinstitute.org/blog/?p=29" target="_blank">обиженную заметку</a> «<em>Джоэль неправ насчет моей работы</em>» опубликовал Кент Бек (соавтор TDD и XP). Ну и понеслось. Нашлись как <a title="Unit testing is not (generally) useful" href="http://prehacked.com/60388.html" target="_blank">противники</a> TDD и вообще тестов, так и <a href="http://kolloid.livejournal.com/346457.html" target="_blank">сторонники</a> (в том числе <a title="Joel vs Uncle Bob" href="http://www.suryasuravarapu.com/2009/02/joel-vs-unclebob-relevance-of-tdd-and-solid-principles.html" target="_blank">индийские</a>). bishop3000 высказался <a href="http://bishop-it.ru/?p=119" target="_blank">против использования TDD и тестов для legacy code</a> (справедливо, см. ниже).  Появилось даже интереснейшее <a href="http://news.ycombinator.com/item?id=465317" target="_blank">обсуждение</a> на Hacker News.</p>
<p>Любопытно, что большинство противников тестирования приводит аргументы из разряда «<em>мне Петрович напел, не понравилось</em>» или вообще делают чисто умозрительные заключения. Никто из них не смог сказать «<em>Вот мы в нашем проекте фанатично поддерживали полное покрытие кода тестами, но так умаялись, что решили отказаться от тестов вообще. После этого мы выпустили продукт на месяц раньше срока, и теперь тратим половину рабочего дня на чтение благодарственных писем от пользователей</em>». То есть, натурально, против TDD и тестов выступают люди, которые ни того, ни другого не пробовали — максимум прочитали пару статей, на основе которых и сформировали свое мнение. Джоэль, выходит, тоже пусть лучше пишет блог, чем код. <em>Но Этвуд?</em> Может, они его там в StackOverflow на наркотиках держат?</p>
<p>Мое мнение — <strong>и TDD, и навыками написания модульных тестов должен в полной мере овладеть каждый уважающий себя программист</strong>. Существуют случаи, когда ни то, ни другое применять нет смысла (например, при создании прототипов). Кроме того, 100% покрытия тестами (распространенное заблуждение насчет TDD, что «<em>все должно быть покрыто тестами</em>») — штука действительно сродни мифической, и мало где практикуемая. Хотя бы потому, что это никому не нужно. Зачем, в самом деле, тестировать геттеры/сеттеры? Или настолько тривиальный код, что вы готовы головой за него поручиться?</p>
<p><strong>Модульный тест — это проверка публичного интерфейса</strong>. Это фундаментальный принцип, из непонимания которого проистекает множество бед. Например, некоторые думают, что если наш класс использует стороннюю библиотеку, то нужно сначала написать для этой библиотеки тесты. Неверно! Тесты писать нужно для нашего класса, и если поведение класса будет нарушено из-за ошибок библиотеки, тесты на это отреагируют. Та же логика применима и к пресловутому вопросу «<em>как тестировать закрытые методы</em>». Их не нужно тестировать! Если открытые методы протестированы и работают правильно, то закрытые никого не интересуют.</p>
<p>Ну, и наконец, заявление Спольски, что, мол, если понадобится что-то поменять, то придется править много тестов, очевидно вопиюще неверное. Модульные тесты на то и модульные, что&#8230; сможете сами догадаться? Вот-вот. И если в вашем коде изменение в одном месте обрушает все остальное — грош вам цена как программисту.</p>
<p>К сожалению, под «программистами» сейчас понимаются все те, кто пишет программы. Но в действительности среди них можно выделить два класса: те, кто подходит к делу систематически и «по-инженерному», и те, кто просто пишет много кода, надеясь на свой опыт. Представьте, например, строителя, который кладет кирпичи «на глазок», руководствуется в работе карандашным эскизом, а перпендикулярность определяет, прищуривши глаз и наклонив голову. Я видел результаты работы таких строителей.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/02/tdd-unit-tests/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Грабли: замена макросов на функции в C</title>
		<link>http://typedef.ru/2009/01/macro-to-function/</link>
		<comments>http://typedef.ru/2009/01/macro-to-function/#comments</comments>
		<pubDate>Tue, 27 Jan 2009 09:41:45 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[грабли]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=123</guid>
		<description><![CDATA[Произошел со мной недавно один случай. Преамбула: наш отдел разрабатывает ОС реального времени для военных целей, а другой отдел разрабатывает некий софт (неважно, какой именно), который под этой ОС работает. ОС поставляется в виде набора библиотек и заголовочников, а процесс сборки заключается в том, что весь пользовательский софт статически компонуется вместе с ОС в единый [...]]]></description>
			<content:encoded><![CDATA[<p>Произошел со мной недавно один случай. Преамбула: наш отдел разрабатывает ОС реального времени для военных целей, а другой отдел разрабатывает некий софт (неважно, какой именно), который под этой ОС работает. ОС поставляется в виде набора библиотек и заголовочников, а процесс сборки заключается в том, что весь пользовательский софт статически компонуется вместе с ОС в единый монолитный образ, который и загружается на целевую машину. А поскольку все это дело военное, то сопровождается такими захватывающими мероприятиями, как предварительные и государственные испытания, сдача программного продукта в архив и т.д. Кто в ящиках работал, тот знает.</p>
<p>Теперь собственно случай. Понадобилось мне поменять кое-какой код в libc. Гляжу в заголовочный файл — а там некоторые функции и не функции вовсе, а макросы. Ну, думаю, непорядок. Заменил макросы на нормальные функции, подправил их как требовалось, тесты соответствующие написал — все замечательно работает.</p>
<p>Через пару дней прибегает представитель соседнего отдела и говорит, что у них все падает и плющится, и все по вине моих функций. Иду разбираться. Гляжу — компоновщик не может найти функции, которые вызывались в старых макросах. Ну делов-то, говорю, пересоберите проект, я там макросы на функции заменил. Какой тут крик начался&#8230; У них же софтина уже прошла испытания, и они ее в архив сдали, вместе с контрольной суммой. Пересобрать ее — значит заново кучу бумажной волокиты произвести. Ой&#8230;</p>
<p>Что поделать, пересобрали. А я с тех пор к макросам отношусь с большой осторожностью.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/01/macro-to-function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Почем образование?</title>
		<link>http://typedef.ru/2009/01/how-much-is-education/</link>
		<comments>http://typedef.ru/2009/01/how-much-is-education/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 14:52:05 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[обучение]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=116</guid>
		<description><![CDATA[Ехал сегодня на работу и слышал по радио (кажется, это было «Эхо Москвы») презабавнейшую дискуссию. Суть ее в том, что предлагалось в связи с кризисом как-то помочь родителям, оплачивающим обучение детей. Ну там, беспроцентные кредиты и подобная ерунда. Высказывалось даже такое радикальное мнение, как запретить брать деньги со студентов вообще. По этому поводу у меня [...]]]></description>
			<content:encoded><![CDATA[<p>Ехал сегодня на работу и слышал по радио (кажется, это было «Эхо Москвы») презабавнейшую дискуссию. Суть ее в том, что предлагалось в связи с кризисом как-то помочь родителям, оплачивающим обучение детей. Ну там, беспроцентные кредиты и подобная ерунда. Высказывалось даже такое радикальное мнение, как запретить брать деньги со студентов вообще. По этому поводу у меня возникли некоторые мысли, которыми я не могу не поделиться.</p>
<p>Многие ВУЗы сейчас живут большей частью на деньги, которые стригут с сердобольных родителей. Более того, даже зарплаты преподавателей (по неподтвержденным данным) напрямую зависят от того, скольких они обучают платников. Сделать все образование бесплатным — значит обречь на вымирание добрую половину российских институтов, заодно с преподавателями. Разумеется, так не будет. Не то чтобы я верю в здравый смысл наших властей. Я верю в силу откатов. И поэтому платное образование никуда не денется.</p>
<p>Идеи о субсидировании малоимущих родителей платников я даже и рассматривать не буду. Образование — такой же товар, как и все остальное. Если у меня денег на машину не хватает, мне тоже государство подкинет?</p>
<p>Ну и теперь самое главное: в чем высший смысл платного образования? Ну например, приходят два студента — Вася и Петя — поступать в машиностроительный институт. Вася блестяще сдает экзамены, поступает на бюджетную форму обучения. Петя экзамены благополучно заваливает, но щедрый Петин родитель говорит: «Фигня вопрос, да неужто я позволю сыну в армию пойти?!» В результате Петя учится с Васей в одной группе, но если Вася старательно грызет гранит науки, и защищает красный диплом, то Петя на учебу кладет все что может, и в результате едва вытягивает на диплом, получив трояк с минусом. Платник ведь, нельзя заваливать. Вася затем едет в Штаты и работает в Chrysler, а Петя устраивается на ВАЗ. Дальнейшая импликация, думаю, понятна.</p>
<p>Ситуация становится еще более пикантной, если рассмотреть подруг Васи и Пети, которые поступали в медицинский по тому же сценарию&#8230;</p>
<p>Единственное вменяемое решение этой проблемы, на мой взгляд — делать одни специальности исключительно платными, а другие — исключительно бесплатными. Ну, например, развелось у нас слишком много экономистов — сделать экономическое образование платным. А если вдруг, наоборот, коварный вирус выкосил всех юристов, юридическое образование оплачивать из бюджета. Возможен еще вариант делать платными «прибыльные» специальности, типа финансистов или стоматологов. Как бы то ни было, нельзя мешать платное с бесплатным на одной специальности. Или так, или этак.</p>
<p>Но самое главное: ни в коем случае <strong>нельзя к платникам относиться как к людям, покупающим диплом в рассрочку</strong>! К ним должны предъявляться те же требования на вступительных экзаменах, и их точно так же нужно гнать из ВУЗа, если завалят сессию. Иначе страна так и останется в том месте организма, в котором она обитает уже почти 20 лет. Жаль только, что в действительности все идет как раз по худшему сценарию, и с каждым годом мы углубляемся все выше в сторону желудка.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/01/how-much-is-education/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Как работать с библиографическими источниками</title>
		<link>http://typedef.ru/2009/01/bib-sources-howto/</link>
		<comments>http://typedef.ru/2009/01/bib-sources-howto/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 20:52:11 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[наука]]></category>
		<category><![CDATA[обучение]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=105</guid>
		<description><![CDATA[Для всех, я думаю, очевидно, что научные работы не пишутся в вакууме. Будь ты хоть трижды гением, в гробу видавшим всех остальных авторов по своей теме, все равно — без анализа существующих наработок не обойтись. Хотя бы для того, чтобы убедиться, что до тебя кто-нибудь не написал то же самое, и ознакомиться с принятой терминологией. [...]]]></description>
			<content:encoded><![CDATA[<p>Для всех, я думаю, очевидно, что научные работы не пишутся в вакууме. Будь ты хоть трижды гением, в гробу видавшим всех остальных авторов по своей теме, все равно — без анализа существующих наработок не обойтись. Хотя бы для того, чтобы убедиться, что до тебя кто-нибудь не написал то же самое, и ознакомиться с принятой терминологией. А если не принимать в расчет этих мифических гениев, то всем ученым так или иначе приходится опираться на результаты своих предшественников. А это десятки и сотни статей, технических отчетов, монографий, докладов&#8230;</p>
<p>Когда я писал магистерскую диссертацию, для меня стало откровением, насколько непростая это штука — работать с литературой. Читаешь одну статью — вроде все понятно. Читаешь другую — все замечательно. Самооценка растет, в голове плещутся новые знания, жизнь прекрасна. Но где-то на десятой статье я стал забывать, что читал раньше. Ну то есть в общих чертах помнил, что вроде бы там написано о том и о сём, но вот что конкретно — хоть режьте, вылетело из головы. Приходилось искать нужную статью и просматривать ее снова и снова. Но это только одна сторона. Самое неприятное наступает, когда ты излагаешь прочитанное в своей работе, а вспомнить, где ты это читал, чтобы поставить ссылку — не можешь. Не говоря уже о том, что какие-то знания могут просто забыться начисто, а это чревато снижением качества работы и даже непроизвольным плагиатом. Вот тут-то и понимаешь, что голова не резиновая, и что фаршировать ее информацией бесконечно без потери качества невозможно. В общем, намучился я с этим делом от души.</p>
<p>Когда поступил в аспирантуру, я решил не наступать на те же грабли и подойти к проблеме системно. <strong>Нужен был какой-то метод, как быстро прорабатывать и систематизировать информацию, да еще и не пропустить при этом чего-то важного.</strong> И после не слишком продолжительных размышлений я сформулировал для себя следующее.</p>
<p>Во-первых, нужно сразу <strong>ввести четкую классификацию всех источников</strong>. Как именно это делать — назначением тегов, организацией иерархии, простым распределением по категориям или как-то еще — каждый решает для себя сам. Лично я просто распределил все по семи категориям без вложенности, пока этого хватает с избытком. Если источник доступен только в бумажном виде, нужно как-то пометить его место в классификации (карандашиком или, еще лучше, цветными наклейками).</p>
<p>Затем нужно <strong>определить порядок</strong>, в котором будет прорабатываться информация. Я сделал это, распределив источники по трем группам:</p>
<ol>
<li>фундаментальная и общая информация по основной теме;</li>
<li>частная информация по основной теме и общая информация по смежным темам;</li>
<li>все остальное.</li>
</ol>
<p>Читать надо именно в таком порядке: <strong>от общего к частному</strong>. В каждой категории лучше читать сначала самое большое и фундаментальное, и только потом переходить к частностям. Иначе говоря, начать с учебников и монографий, и закончить статьями и прочей мелочью. Желательно упорядочить проработку источников <strong>в хронологическом порядке</strong>, чтобы не путать устаревшее с актуальным.</p>
<p>Теперь для каждого очередного источника нужно сделать следующее:</p>
<ol>
<li><strong>распечатать</strong>, если он в электронном виде;</li>
<li><strong>прочитать, подчеркивая ключевые фразы</strong> и делая пометки; не нужно подчеркивать все подряд — только основные идеи;</li>
<li><strong>выбрать ключ</strong>, под которым будет фигурировать этот источник; я обычно комбинирую фамилию автора, год и один-два ключевых слова, например, «fidge2002schedtest»;</li>
<li><strong>записать выходные данные</strong> и ключ в библиографическую базу (я пользуюсь BibTeX и <a title="Ebib" href="http://typedef.ru/2009/01/ebib/" target="_blank">ebib</a>);</li>
<li><strong>составить краткий конспект</strong>, переписав, по сути, все подчеркнутые фрагменты; при этом совсем не обязательно должен получиться связный текст; вы можете даже использовать <a title="Бесплатные программы для mind mapping" href="http://en.wikipedia.org/wiki/List_of_mind_mapping_software" target="_blank">mind maps</a>, если вам так удобнее; я предпочитаю делать конспект, полностью отражающий структуру исходного текста (то есть, всю иерархию разделов), но некоторые разделы, не представляющие особого интереса, оставляю пустыми; все это делаю в LaTeX, чтобы можно было распечатать и почитать на досуге;</li>
<li>посмотреть, <strong>нет ли чего интересного в библиографии</strong> источника;</li>
<li>не забыть <strong>вписать в конспект путь к файлу</strong> источника;</li>
<li>на твердой копии или оригинале источника надписывается выбранный библиографический ключ.</li>
</ol>
<p>Второй шаг можно отделить. Я, например, читаю и размечаю статьи, когда еду в метро. Обычно на 30-страничную статью уходит две-три поездки на работу и с работы. Конспектирование идет гораздо медленнее, в среднем от 2 до 6 часов на статью, в зависимости от раздела. Поэтому у меня всегда есть запас прочитанных, но не законспектированных статей.</p>
<p>Ну вот, собственно. Надеюсь, кому-нибудь пригодится в научной работе. Буду рад, если поделитесь своими способами организации работы с текстами.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/01/bib-sources-howto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ebib’лиотекарь</title>
		<link>http://typedef.ru/2009/01/ebib/</link>
		<comments>http://typedef.ru/2009/01/ebib/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 20:13:00 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[emacs]]></category>
		<category><![CDATA[LaTeX]]></category>
		<category><![CDATA[инструменты]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=83</guid>
		<description><![CDATA[Все началось с того, что я подсел на emacs. Путь юного джедая был долог и тернист, но в конце концов я вынужден был согласиться, что да, иногда emacs оказывается эффективнее, чем другие редакторы и IDE. И что если уж подсел — то все, организм начинает отторгать все остальное. Не иначе как специальный гормон начинает вырабатываться, [...]]]></description>
			<content:encoded><![CDATA[<p>Все началось с того, что я подсел на emacs. Путь юного джедая был долог и тернист, но в конце концов я вынужден был согласиться, что да, иногда emacs оказывается эффективнее, чем другие редакторы и IDE. И что если уж подсел — то все, организм начинает отторгать все остальное. Не иначе как специальный гормон начинает вырабатываться, вызвающий эйфорию при пользовании emacs и депрессию вместе с неконтролируемыми вспышками гнева — во всех остальных случаях. А уж какие ощущения емаксист испытывает при редактировании своего ~/.emacs, не стоит даже и пытаться описывать&#8230;</p>
<p>Нет, конечно, с первого раза он мне не понравился. И со второго, и с третьего тоже. Но я был настойчив, потому что хотел убедиться, что все эти странные люди со Столлманом во главе ошибаются. Наивный&#8230; Майн готт, я даже нашел людей, которые пользуются emacs в Windows! Теперь я могу их понять. Чем дальше, тем меньше хочется переключаться в другое окно. Нужна оболочка — пожалуйста, M-x shell. Почту почитать — сколько угодно, rmail-mode. С файлами и каталогами поработать — вот, извольте, C-x d. Рисунок нарисовать, PDF посмотреть, по Интернету посерфить&#8230; Ах да, в нем еще можно редактировать текст (вот ведь приятная неожиданность)! В результате ловишь себя на мысли, что и Linux в общем-то не очень нужен, и только зря жрет ресурсы.</p>
<p>Но падаван вырос, и настало ему время заняться поддержкой многострадальной отечественной науки. Наука у нас в стране, говоря откровенно, каким-то парадоксальным образом существует отдельно от занимающихся ею ученых, в своеобразной параллельной реальности. Оцените: <a title="Программные системы" href="http://swsys.ru/" target="_blank">ВАКовский журнал</a> требует предоставлять публикации <em>в формате Word</em>, и чтоб <em>не более 5 страниц</em>. Вместе с иллюстрациями и библиографией. Видели когда-нибудь нормальную научную статью из 5 страниц? Найдете — покажите мне. А уж статей, качественно сверстанных в Word, — днем с огнем; большинство просто не в курсе про такую вещь, как стили.  Но я на поводу у толпы не иду и как правильный апологет CS все пишу исключительно в (La)TeX. Потом как-нибудь через ODF и MathML сконвертирую, если припрет.</p>
<p>Но что-то меня сегодня понесло на отвлеченные темы болтать, пора бы перейти к делу. Так вот, поскольку emacs теперь мой дом родной, то <a title="AUCTeX" href="http://xtalk.msk.su/~ott/ru/writings/emacs-tex/AUCTeX.html" target="_blank">AUCTeX</a> — просто-таки домашние тапочки, основная работа происходит именно в нем. Но какой же научный текст без библиографии? Вот и пришлось искать некий <strong>редактор BibTeX-файлов, встроенный в emacs</strong> (кто не в курсе, про что вообще речь и зачем он нужен, почитайте <a title="Библиография в LaTeX" href="http://mydebianblog.blogspot.com/2006/11/latex-jabref.html" target="_blank">обзор BibTeX от Дебианщика</a>). Таковым редактором оказался <a title="Ebib" href="http://ebib.sourceforge.net/" target="_blank">ebib</a>. Это не режим никакой, а полноценное elisp-приложение, вроде Gnus.</p>
<p>ebib прост, как пятак. Для начала в ~/.emacs записываем строчку:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>autoload 'ebib <span style="color: #ff0000;">&quot;ebib&quot;</span> <span style="color: #ff0000;">&quot;Ebib, a BibTeX database manager.&quot;</span> t<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Теперь запускаем его по <strong>M-x ebib</strong>, видим два буфера: верхний (индексный, <em>index buffer</em>) и нижний (буфер записи, <em>entry buffer</em>). В индексном буфере отображается список ключей всех записей в bib-базе. При выборе одного из ключей в буфере записи отображаются поля, описывающие соответствующий библиографический источник.</p>
<p style="text-align: center;">
<p style="text-align: center;"><a title="Ebib" rel="lightbox[pics83]" href="http://typedef.ru/wp-content/uploads/2009/01/ebib.png"><img class="attachment wp-att-101 centered" src="http://typedef.ru/wp-content/uploads/2009/01/ebib.thumbnail.png" alt="Ebib" width="400" height="284" /></a></p>
<p>Я не буду подробно и по шагам описывать, как именно пользоваться ebib — дело нехитрое. Лучше приведу небольшой набор наиболее полезных привязок:</p>
<ul>
<li><strong>o</strong> —открыть (создать) bib-файл;</li>
<li><strong>q</strong> —выйти из ebib совсем (в индексном буфере) или завершить редактирование записи (в буфере записи);</li>
<li><strong>z</strong> — отправить ebib на задний план, без закрытия файла (вернуть обратно опять по <strong>M-x ebib</strong>);</li>
<li><strong>a</strong> — добавить запись;</li>
<li><strong>e</strong> — редактировать запись (в индексном буфере) или поле (в буфере записи);</li>
<li><strong>E</strong> —изменить ключ записи;</li>
<li><strong>C-x b</strong> —завершить редактирование многострочного поля;</li>
<li><strong>c, x, y</strong> —copy, cut, yank;</li>
<li><strong>s</strong> — сохранить файл;</li>
<li><strong>w</strong> — сохранить файл в другое место;</li>
<li><strong>/</strong> — поиск в базе по регулярному выражению;</li>
<li><strong>P</strong> — сформировать файл с таблицей всех записей в базе (мегаудобная штука!).</li>
</ul>
<p>Теперь о самом главном — об интеграции с LaTeX-mode. Это происходит с двух сторон. Если мы редактируем tex-файл (то есть, находимся в LaTeX-mode), то в нашем распоряжении есть две замечательные функции:</p>
<ul>
<li><em><strong>ebib-insert-bibtex-key</strong></em> — в позицию курсора вставляется ссылка на источник, ключ которого мы зададим в минибуфере (при этом работает автодополнение!);</li>
<li><em><strong>ebib-entry-summary</strong></em> — отобразить информацию о цитате, на которой находится курсор.</li>
</ul>
<p>По умолчанию эти функции не закреплены за клавиатурными комбинациями, поэтому рекомундую сразу дописать в ~/.emacs следующее:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>add-hook 'LaTeX-mode-hook #'<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>local-set-key <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\C</span>-cb&quot;</span> 'ebib-insert-bibtex-key<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span>add-hook 'LaTeX-mode-hook #'<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>local-set-key <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\C</span>-cs&quot;</span> 'ebib-entry-summary<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Разумеется, для корректной работы на заднем плане в это время должен работать ebib. Если же мы находимся в индексном буфере ebib&#8217;a, то можем выбрать ключ и нажать <strong>p</strong> (<em>push</em>), вставив тем самым цитату в некоторый другой буфер. Это хорошо тем, что перед глазами сразу вся база, и не нужно мучительно вспоминать имена ключей.</p>
<p>Разумеется, я тут рассказал только самые-самые верхи. Жаждущих подробностей перенаправляю читать <a title="Ebib Manual" href="http://ebib.sourceforge.net/manual/ebib-manual.html" target="_blank">документацию</a>.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2009/01/ebib/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Вышел Python 3.0</title>
		<link>http://typedef.ru/2008/12/python3-released/</link>
		<comments>http://typedef.ru/2008/12/python3-released/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 09:26:36 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[новости]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=71</guid>
		<description><![CDATA[Больше, собственно, сказать нечего. Всех заинтересованных поздравляю. Подробности.
]]></description>
			<content:encoded><![CDATA[<p>Больше, собственно, сказать нечего. Всех заинтересованных поздравляю. <a title="Python 3.0: What's New" href="http://docs.python.org/dev/3.0/whatsnew/3.0.html" target="_blank">Подробности</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/12/python3-released/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Висячая пунктуация в LaTeX</title>
		<link>http://typedef.ru/2008/12/latex-protrusion/</link>
		<comments>http://typedef.ru/2008/12/latex-protrusion/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 12:38:24 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[LaTeX]]></category>
		<category><![CDATA[текст]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=66</guid>
		<description><![CDATA[Висячая пунктуация (protrusion) — это свешивание некоторых пунктуационных символов (дефисов, кавычек, скобок, запятых и т.п.) за границу текста. Обычно применяется при полной выключке. Предназначена для оптического выравнивания границ текста: знаки пунктуации имеют меньший визуальный вес, поэтому если их свесить, граница текста будет казаться ровнее.
Подробнее можно посмотреть, например, у Лебедева или погуглить.
Реализовать висячую пунктуацию можно в [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Висячая пунктуация (protrusion)</strong> — это свешивание некоторых пунктуационных символов (дефисов, кавычек, скобок, запятых и т.п.) за границу текста. Обычно применяется при полной выключке. Предназначена для оптического выравнивания границ текста: знаки пунктуации имеют меньший визуальный вес, поэтому если их свесить, граница текста будет казаться ровнее.</p>
<p>Подробнее можно посмотреть, например, <a title="Ководство: висячая пунктуация" href="http://www.artlebedev.ru/kovodstvo/sections/120/" target="_blank">у Лебедева</a> или погуглить.</p>
<p>Реализовать висячую пунктуацию можно в разных типографских программах, таких как Adobe InDesign. Можно даже сделать <a href="http://www.promoforum.ru/index.php?showtopic=11068" target="_blank">в Web-страницах</a>, и даже <a href="http://habrahabr.ru/blogs/webdev/26585/" target="_blank">динамически</a>. Но везде это сопряжено с известными трудностями: нельзя просто сказать «а сделай-ка мне висячую пунктуацию» и беззаботно топтать текст. Наиболее просто вариант предлагает LaTeX: нужно просто вставить следующие настройки в преамбулу:</p>

<div class="wp_syntax"><div class="code"><pre class="latex" style="font-family:monospace;"><span style="color: #800000; font-weight: normal;">\usepackage</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">microtype</span><span style="color: #E02020; ">}</span>
<span style="color: #800000; font-weight: normal;">\SetProtrusion</span>
<span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">
encoding = T2A,
family = faq
</span><span style="color: #E02020; ">}</span>
<span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">
« = <span style="color: #E02020; ">{</span>1000,     </span><span style="color: #E02020; ">}</span>,
» = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    , 1000</span><span style="color: #E02020; ">}</span>,
„ = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">1000,     </span><span style="color: #E02020; ">}</span>,
“ = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    , 1000</span><span style="color: #E02020; ">}</span>,
( = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">1000,     </span><span style="color: #E02020; ">}</span>,
) = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    , 1000</span><span style="color: #E02020; ">}</span>,
! = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    , 1000</span><span style="color: #E02020; ">}</span>,
? = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    , 1000</span><span style="color: #E02020; ">}</span>,
: = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    , 1000</span><span style="color: #E02020; ">}</span>,
; = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    , 1000</span><span style="color: #E02020; ">}</span>,
. = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    , 1000</span><span style="color: #E02020; ">}</span>,
- = <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    ,  500</span><span style="color: #E02020; ">}</span>,
<span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">,</span><span style="color: #E02020; ">}</span>= <span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">    , 1000</span><span style="color: #E02020; ">}</span>
<span style="color: #E02020; ">}</span>
<span style="color: #800000; font-weight: normal;">\DeclareMicrotypeSet</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">t2atext</span><span style="color: #E02020; ">}{</span><span style="color: #2020C0; font-weight: normal;">encoding=T2A</span><span style="color: #E02020; ">}</span>
<span style="color: #800000; font-weight: normal;">\UseMicrotypeSet</span><span style="color: #E02020; ">{</span><span style="color: #2020C0; font-weight: normal;">t2atext</span><span style="color: #E02020; ">}</span></pre></div></div>

<p>Чтобы все это заработало, придется установить последнюю версию пакета <a title="CTAN: microtype" href="http://www.ctan.org/tex-archive/macros/latex/contrib/microtype/" target="_blank">microtype</a>. Параметр <strong>faq</strong> в приведенном выше коде — это семейство шрифтов. Здесь я использую пакет шрифтов <a title="pscyr" href="http://www.tex.uniyar.ac.ru/package/fonts/pscyr/" target="_blank">pscyr</a> и семейство антиквенных шрифтов (aq).</p>
<p style="text-align: center;"><a title="Висячая пунктуация" rel="lightbox[pics66]" href="http://typedef.ru/wp-content/uploads/2008/12/protrusion.png"><img class="attachment wp-att-68 centered" src="http://typedef.ru/wp-content/uploads/2008/12/protrusion.thumbnail.png" alt="Висячая пунктуация" width="320" height="181" /></a></p>
<p style="text-align: left;">
<p>Идея взята из <a href="http://www.rsdn.ru/Forum/message/3094072.1.aspx" target="_blank">поста Roman Odaisky</a> на РСДН и <a href="http://ogolberg.livejournal.com/26404.html" target="_blank">ЖЖ-поста ogoldberg</a>.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/12/latex-protrusion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ген программизма</title>
		<link>http://typedef.ru/2008/11/programmer-gene/</link>
		<comments>http://typedef.ru/2008/11/programmer-gene/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 21:23:02 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[обучение]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=63</guid>
		<description><![CDATA[Все без исключения мужики, которые умеют водить машину, убеждены до глубины души — гены, отвечающие за пол и цвет волос, непосредственным образом связаны со способностью адекватно вести себя на дороге. Говоря проще, блондинки просто физиологически не способны научиться нормально водить (хотя к некоторым немкам это, видимо, не относится). Не могу ничего определенного сказать по этому [...]]]></description>
			<content:encoded><![CDATA[<p>Все без исключения мужики, которые умеют водить машину, убеждены до глубины души — гены, отвечающие за пол и цвет волос, непосредственным образом связаны со способностью адекватно вести себя на дороге. Говоря проще, блондинки просто <em>физиологически</em> не способны научиться нормально водить (хотя к <a title="Ютта Кляйншмидт" href="http://www.autoracer.ru/racing/racing_60.html" target="_blank">некоторым немкам</a> это, видимо, не относится). Не могу ничего определенного сказать по этому поводу, поскольку мастерство единственной знакомой блондинки-водителя еще не успел оценить. Зато с удивлением недавно понял, что природная склонность совершенно необходима для занятия программированием!</p>
<p>Не стоит сразу меня обвинять в мракобесии и развешивать ярлыки. Как ни удивительно, проблема склонности к программированию существует, и люди даже пишут по этому поводу <a title="The camel has two humps" href="http://www.cs.mdx.ac.uk/research/PhDArea/saeed/paper1.pdf" target="_blank">серьезные статьи</a>. В статье заявляется с известной долей недоумения, что, оказывается, <strong>существует способ сказать до начала обучения, сумеет ли человек осилить программирование</strong> или лучше сразу на рудники. Нехило так, а? Приходит студент поступать на программерскую кафедру, а его просят ответить на три простых вопроса, после чего (голосом магистра Йоды): &laquo;<em>Тебя обучать не будем мы! Силы в тебе увидеть не можем!..</em>&raquo;</p>
<p>Я бы, наверное, принял все это за шутку, если бы сам не столкнулся с живым подтверждением. Однажды я попробовал в порядке развлечения научить азам программирования двух людей. Один из них <em>не смог понять, как работает присваивание значений переменным</em>. То есть, натурально, пришлось минут 20 объяснять, что означает запись <code>a = 1</code>. Другой человек воспринял концепцию присваивания легко и непринужденно, хотя никогда до этого не программировал, да и желания такого не имел. Каково же было мое удивление, когда я наткнулся на <a title="Coding Horror" href="http://www.codinghorror.com/blog/archives/000635.html" target="_blank">пост Джеффа Этвуда</a>, откуда и узнал про существование исследования в этой области. И вопрос на понимание присваивания у них первый в списке!</p>
<p>В общем, как ни крути, существует разница между людьми. Одни могут <em>в уме строить и выполнять модели дискретных структур</em>, а другие — не могут. Одни люди потенциально могут стать программистами, а другие — нет. Конечно, есть масса людей, зарабатывающих деньги программированием, но неспособные понять рекурсию, косвенную адресацию или функциональную парадигму. Но это другое — такие люди не строят ментальные модели программ, они просто <a title="Why Johnny can't program" href="http://www.bricklin.com/wontprogram.htm" target="_blank">действуют по аналогии</a> или используют упрощенные способы формализации (строительство SQL-запросов мышкой в Access), и хакеров из них не получится ни при каком раскладе.</p>
<p>Ну и самое главное — список понятий, которые настоящий программист должен понимать. Причем не умом, а подсознанием, <em>интуитивно</em> — словами ведь всякий может рассказать, что такое рекурсия, если ему достаточно долго это повторять. Итак, необходимо понимать:</p>
<ul>
<li>присваивание;</li>
<li>последовательное выполнение;</li>
<li>циклы;</li>
<li>рекурсию;</li>
<li>косвенную адресацию (указатели);</li>
<li>мультипрограммирование (многопоточность);</li>
<li>&laquo;чувство правильной вещи&raquo;.</li>
</ul>
<p>Я несколько расширил список, приведенный в вышеупомянутом исследовании, добавив косвенность и &laquo;<em>чувство правильной вещи</em>&laquo;. Под последним подразумевается нечто вроде программистского здравого смысла, способность выбрать из нескольких способов реализации одного и того же самый &laquo;правильный&raquo; и &laquo;красивый&raquo; вариант. Причем не формулируя критерии, по которым сделан выбор.</p>
<p>Попробуйте испытать своих некомпьютерных знакомых и убедитесь, что ген программизма таки существует. Ну а не убедитесь — бросайте в меня камень, чего уж там.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/11/programmer-gene/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>typedef</title>
		<link>http://typedef.ru/2008/11/typedef/</link>
		<comments>http://typedef.ru/2008/11/typedef/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 08:47:43 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=61</guid>
		<description><![CDATA[Ко мне в блог регулярно приходят люди по поисковым запросам вроде «typedef», «как работает typedef» или «что такое typedef пожалуйста помогите». Ничего удивительного — написанное аршинными буквами ключевое слово языка Си в заголовке может запутать не только поисковые машины. Посему не смею больше вводить в заблуждение своих читателей, публикую небольшой ликбез на тему.
typedef — это [...]]]></description>
			<content:encoded><![CDATA[<p>Ко мне в блог регулярно приходят люди по поисковым запросам вроде <em>«typedef</em>», <em>«</em><em>как работает typedef</em>» или <em>«</em><em>что такое typedef пожалуйста помогите</em>». Ничего удивительного — написанное аршинными буквами ключевое слово языка Си в заголовке может запутать не только поисковые машины. Посему не смею больше вводить в заблуждение своих читателей, публикую небольшой ликбез на тему.</p>
<p><code>typedef</code> — это <strong>способ создания синонима типа</strong>. Ничего сакрального при этом не происходит, и программы не приобретают никаких особых свойств. Просто иногда это позволяет несколько упростить код, освободив его от таинственных определений вроде:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>signal<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> sig<span style="color: #339933;">,</span> <span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>func<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Приведенная декларация является потолком сложности среди встречающихся на практике определений. Авторы книг по Си могут сколько угодно приводить примеры <em>«</em><em>массива указателей на функции, принимающих указатели на массив структур и возвращающих константный указатель на функцию, возвращающую&#8230; бла-бла-бла</em>». Такие извращения реально встречаются в одной программе из тысячи. Да и то, при виде такого нужно усомниться во вменяемости автора.</p>
<p>Короче говоря, <code>typedef</code> используется для <strong>сокращения сложных или просто длинных определений типов</strong>, или же для <strong>сокрытия реально используемых типов</strong>, например, для облегчения портирования.</p>
<p>Синтаксис <code>typedef</code> очень прост: мы пишем обычное объявление стековой переменной и добавляем перед этим определением ключевое слово <code>typedef</code>. При этом никакая переменная не создается, а имя &laquo;переменной&raquo; становится синонимом указанного типа. Например:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">const</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span> <span style="color: #993333;">string</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* string - указатель на константный символ */</span>
<span style="color: #993333;">typedef</span> <span style="color: #993333;">void</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>fptr<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* fptr - указатель на функцию, возвращающую void и принимающую int */</span></pre></div></div>

<p>Часто можно видеть, как с помощью <code>typedef</code> можно избавиться от необходимости писать <code>struct</code> при определении переменной типа структуры:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> s_tag <span style="color: #009900;">&#123;</span>
<span style="color: #808080; font-style: italic;">/* какие-то члены */</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> s_tag mystruct<span style="color: #339933;">;</span>
<span style="color: #808080; font-style: italic;">/* ... */</span>
mystruct s<span style="color: #339933;">;</span></pre></div></div>

<p>Можно создать синоним одновременно с определением структуры:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> s_tag <span style="color: #009900;">&#123;</span>
<span style="color: #808080; font-style: italic;">/* какие-то члены */</span>
<span style="color: #009900;">&#125;</span> mystruct<span style="color: #339933;">;</span></pre></div></div>

<p>Можно даже создать синоним для безымянной структуры:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> <span style="color: #009900;">&#123;</span>
<span style="color: #808080; font-style: italic;">/* какие-то члены */</span>
<span style="color: #009900;">&#125;</span> mystruct<span style="color: #339933;">;</span></pre></div></div>

<p>Начинающие программисты вместо <code>typedef</code> часто используют препроцессор:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define mystruct struct s_tag</span></pre></div></div>

<p>Хотя со структурами вроде бы никаких проблем не возникает, использование в общем случае препроцессора для создания псевдонима типа может привести к трудноуловимым ошибкам:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define iptr int*</span>
iptr ptr1<span style="color: #339933;">,</span> ptr2<span style="color: #339933;">;</span> <span style="color: #808080; font-style: italic;">/* какой тип у ptr2? */</span></pre></div></div>

Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/11/typedef/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Кэширование и буферизация</title>
		<link>http://typedef.ru/2008/10/cache-vs-buffer/</link>
		<comments>http://typedef.ru/2008/10/cache-vs-buffer/#comments</comments>
		<pubDate>Fri, 17 Oct 2008 19:57:43 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[структуры данных]]></category>
		<category><![CDATA[устройство ОС]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=57</guid>
		<description><![CDATA[У меня с институтских времен осталась незалеченная психологическая травма. Преподаватель по курсу &#171;Проектирование операционных систем&#171;, человек во всех отношениях уважаемый и компетентный, однажды высказал утверждение: &#171;Кэширование и буферизация — это одно и то же, только кэширование относится к физическому хранению данных, а буферизация — к логическому&#171;. Интуиция моя возопила, я чувствовал, что где-то тут подвох, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">У меня с институтских времен осталась незалеченная психологическая травма. Преподаватель по курсу &laquo;<em>Проектирование операционных систем</em>&laquo;, человек во всех отношениях уважаемый и компетентный, однажды высказал утверждение: &laquo;<em>Кэширование и буферизация — это одно и то же, только кэширование относится к физическому хранению данных, а буферизация — к логическому</em>&laquo;. Интуиция моя возопила, я чувствовал, что где-то тут подвох, но не смог привести убедительные аргументы против. В том числе и на экзамене (за что и получил единственную четверку в диплом). Попробую реабилитироваться и прояснить ситуацию. Все что я написал ниже — мое личное мнение. Но это не значит, что я все это высосал из пальца, некоторую работу по изучению вопроса я все же провел. Итак.</p>
<p style="text-align: justify;"><strong>Кэширование</strong> — это <em>способ ускорения доступа</em> (чтения и записи) к медленной памяти <em>за счет использования более скоростной</em> (обычно существенно меньшего объема). Используемая часть быстрой памяти носит название <strong>кэша</strong>. Фрагменты содержимого медленной памяти, к которым наиболее часто происходит обращение, сохраняются в кэше. При чтении или записи этих фрагментов нет необходимости обращаться к медленной памяти — можно получить нужные данные из кэша или, напротив, записать в кэш. В последнем случае потребуется дальнейшая синхронизация кэша с медленной памятью.</p>
<p style="text-align: justify;">Примеры использования кэширования:</p>
<ul>
<li style="text-align: justify;">кэширование отображения виртуальных адресов в физические; медленная память — таблицы преобразования в оперативной памяти, быстрая — кэш TLB;</li>
<li style="text-align: justify;">кэширование обмена данными с жестким диском; медленная память — диск, быстрая — оперативная память;</li>
<li style="text-align: justify;">кэширование веб-страниц (кэш браузера); медленная память — соединение с Интернетом, быстрая — жесткий диск.</li>
</ul>
<p style="text-align: justify;">Как можно видеть, один и тот же вид памяти может в разных случаях выступать и в роли кэша, и в роли медленной памяти.</p>
<p style="text-align: justify;"><strong>Буферизация</strong> — это такая организация обмена данными, при которой <em>используется промежуточное временное хранилище</em> (<strong>буфер</strong>), в котором накапливаются данные, <em>если по какой-то причине прямой обмен нежелателен или невозможен</em>. Причиной, по которой следует избегать прямого обмена, может являться, например:</p>
<ul style="text-align: justify;">
<li>временная неготовность устройства; при прожиге болванок наверняка все видели волшебный Progress Bar &laquo;Уровень буфера&raquo;, это как раз то самое;</li>
<li>невозможность принять поток данных с требуемой скоростью; например, для этих целей существует исходящая очередь сетевых пакетов — приложения могут клепать данные быстрее, чем сетевая карта успеет их передавать;</li>
<li>гранулярность обмена; в этом случае буферизация служит средством группировки данных; яркий пример — жесткий диск, обмен с которым возможен только блоками размером с сектор (512 байт обычно), а лучше даже целыми дорожками (много секторов); это также пример того, как одна и та же структура данных может использоваться и для кэширования, и для буферизации (см. выше пример про кэширование жесткого диска).</li>
</ul>
<p style="text-align: justify;">Буферизация бывает <em>прозрачной</em> и <em>непрозрачной</em>. Прозрачная — когда обменивающиеся данными стороны в курсе, что буфер существует (clipboard, message queue). Непрозрачная буферизация — когда буферизация незаметна (сокеты).</p>
<p style="text-align: justify;">Резюме. <strong>Основная задача кэширования — ускорить, а лучше вообще устранить чтение из медленной памяти. Основная задача буферизации — повысить эффективность записи.</strong></p>
<p style="text-align: justify;">Контрольный вопрос. Что такое буферный кэш?</p>
<p style="text-align: justify;">Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/10/cache-vs-buffer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Минималистичный фреймворк модульных тестов для Си</title>
		<link>http://typedef.ru/2008/10/c-minimal-utest-framework/</link>
		<comments>http://typedef.ru/2008/10/c-minimal-utest-framework/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 08:58:01 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[тестирование]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=51</guid>
		<description><![CDATA[Как-то на работе (а разрабатываем мы ни много ни мало — операционную систему) появилась необходимость писать модульные тесты к разрабатываемым функциям. В силу специфики разработки прикрутить какой-то внешний фреймворк не представлялось возможным. ОС все же вещь в себе, а без автоматизированного тестирования жизнь становится уж слишком непредсказуемой. В общем, пришлось написать свой юнит-тест-фреймворк.
Признаюсь сразу, идею [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Как-то на работе (а разрабатываем мы ни много ни мало — <a href="http://www.niisi.ru/intro1.htm" target="_blank">операционную систему</a>) появилась необходимость писать модульные тесты к разрабатываемым функциям. В силу специфики разработки прикрутить какой-то внешний фреймворк не представлялось возможным. ОС все же вещь в себе, а без автоматизированного тестирования жизнь становится уж слишком непредсказуемой. В общем, пришлось написать свой юнит-тест-фреймворк.</p>
<p style="text-align: justify;">Признаюсь сразу, идею слизал у <a href="http://www.jera.com/techinfo/jtns/jtn002.html" target="_blank">MinUnit</a>, но сам он мне показался неудобным. В результате получился один-единственный заголовочный файл:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#ifndef _UTEST_H_</span>
<span style="color: #339933;">#define _UTEST_H_</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#define UT_ASSERT_EX(expr,fmt,...) \
    do { \
    if (!(expr)) { printf(&quot;ASSERT: file \&quot;%s\&quot;, line %d, function \&quot;%s\&quot;: &quot;,\
            __FILE__, __LINE__, __FUNCTION__); \
            printf(fmt, __VA_ARGS__); \
            printf(&quot;\n&quot;); \
            return 1; } \
    } while(0);</span>
<span style="color: #339933;">#define UT_ASSERT(expr,msg) UT_ASSERT_EX(expr, &quot;%s&quot;, msg)</span>
<span style="color: #339933;">#define UT_TEST(test) \
    do { \
        printf(&quot;TEST: \&quot;%s\&quot; %s\n&quot;, #test, (_t_ ## test() ? &quot;failed&quot; : &quot;OK&quot;)); \
    } while(0);</span>
<span style="color: #339933;">#define UT_TESTDEF(name, body) \
    static int _t_ ## name () { \
        do { \
            body \
        } while(0); \
        return 0; }</span>
<span style="color: #339933;">#endif /*_UTEST_H_*/</span></pre></div></div>

<p style="text-align: justify;">Использование, я полагаю, достаточно очевидно. Но на всякий случай пример:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &quot;utest.h&quot;</span>
&nbsp;
<span style="color: #993333;">int</span> func1<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> arg<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> arg<span style="color: #339933;">*</span>arg<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
UT_TESTDEF<span style="color: #009900;">&#40;</span>func1<span style="color: #339933;">,</span>
    <span style="color: #993333;">int</span> ret<span style="color: #339933;">;</span>
    ret <span style="color: #339933;">=</span> func1<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    UT_ASSERT<span style="color: #009900;">&#40;</span>ret <span style="color: #339933;">==</span> <span style="color: #0000dd;">25</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;blah-blah&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    ret <span style="color: #339933;">=</span> func1<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    UT_ASSERT_EX<span style="color: #009900;">&#40;</span>ret <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;ret is %d, must be 0&quot;</span><span style="color: #339933;">,</span> ret<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    UT_TEST<span style="color: #009900;">&#40;</span>func1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Задачу свою такой подход вполне решает, так что невеликие размеры &laquo;фреймворка&raquo; пусть вас не смущают. Желающие могут навертеть вокруг этого свои рюшечки, а по мне и этого достаточно.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/10/c-minimal-utest-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>День программиста и IOCCC</title>
		<link>http://typedef.ru/2008/09/programmers-day-and-ioccc/</link>
		<comments>http://typedef.ru/2008/09/programmers-day-and-ioccc/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 12:52:28 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[история]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=33</guid>
		<description><![CDATA[Хотя у меня пока, учитывая возраст блога, есть некоторое ощущение &#171;разговора с пустотой&#187;, все же я не могу не поздравить всех немногочисленных моих посетителей с 0&#215;100-ым днем в году. Это тот самый день когда нужно или не работать совсем, или сворачивать горы. У меня получилось второе: напланировал кучу дел, приехал на работу и через полтора [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Хотя у меня пока, учитывая возраст блога, есть некоторое ощущение &laquo;разговора с пустотой&raquo;, все же я не могу не поздравить всех немногочисленных моих посетителей с 0&#215;100-ым днем в году. Это тот самый день когда нужно или не работать совсем, или сворачивать горы. У меня получилось второе: напланировал кучу дел, приехал на работу и через полтора часа уже все сделал. Остается только пожелать всем побольше таких ошибок в планировании. Или это все же сакральное влияние даты?</p>
<p style="text-align: justify;">О серьезных вещах сегодня писать — кощунство, поэтому буду писать о полусерьезных.</p>
<p style="text-align: justify;"><a title="PDP-7" rel="lightbox[pics33]" href="http://en.wikipedia.org/wiki/PDP-7"><img class="attachment wp-att-36 alignleft" src="http://typedef.ru/wp-content/uploads/2008/09/pdp7-oslo-2005.thumbnail.jpeg" alt="PDP-7" width="200" height="150" /></a>В далекие-далекие годы, когда еще только-только стали появляться компьютеры на полупроводниках, а в лесах можно было встретить динозавров, появился UNIX. Дорог он нам не только фактом своего существования, но главным образом сложившейся вокруг него культурой. Ну, знаете, там были такие волосатые очкарики, которые все свое время просиживали за терминалом (при наличии такового),  пили колу и разговаривали друг с другом на языке инопланетян. Эти ненормальные идентифицировали себя &laquo;хакерами&raquo;, все время писали какой-то код и ни во что не ставили интеллектуальную собственность.  Кстати, все ли знают, что UNIX изначально создавался Томпсоном как средство запуска игры <a title="Space Travel" href="http://en.wikipedia.org/wiki/Space_Travel_(video_game)" target="_blank">Space Travel</a> на компьютере PDP-7?</p>
<p style="text-align: justify;">Но нужно отдать должное этим нечесаным парням: в их развлечениях родилось много полезных штук, и, в частности, язык Си. Создали его изначально не для развлечений (хотя кто-то пытается это <a title="Создатели Си разыграли весь мир" href="http://www-users.cs.york.ac.uk/~susan/joke/c.htm" target="_blank">опровергать</a>), а для тотального переписывания Юникса. Но хакеров ведь хлебом не корми — дай любую попавшую в руки сущность разобрать, понять как работает, перекроить и раздать друзьям. Поэтому, учитывая специфику C, нетрудно было догадаться, что мерилом профессионализма, наряду с длиной волос и диоптриями близорукости, станет способность написать самую необычную, изящную, умопомрачительную и непонятную простым смертным программу. Например, такую:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> n<span style="color: #009900;">&#123;</span><span style="color: #993333;">int</span> a<span style="color: #339933;">:</span><span style="color: #0000dd;">3</span><span style="color: #339933;">,</span>
b<span style="color: #339933;">:</span><span style="color: #0000dd;">29</span><span style="color: #339933;">;</span>struct n<span style="color: #339933;">*</span>c<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>t<span style="color: #339933;">;</span>t<span style="color: #339933;">*</span>
f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>r<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>m<span style="color: #009900;">&#40;</span>u<span style="color: #009900;">&#41;</span>t<span style="color: #339933;">*</span>u<span style="color: #339933;">;</span><span style="color: #009900;">&#123;</span>t<span style="color: #339933;">*</span>w<span style="color: #339933;">,*</span>z<span style="color: #339933;">;</span>
z<span style="color: #339933;">=</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">,</span>q<span style="color: #009900;">&#40;</span>z<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">=</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">*</span><span style="color: #0000dd;">10</span><span style="color: #339933;">,</span>
w<span style="color: #339933;">=</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>w<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>a<span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span>w<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>
c<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>t<span style="color: #339933;">*</span>k<span style="color: #339933;">;</span>g<span style="color: #009900;">&#40;</span>u<span style="color: #009900;">&#41;</span>t<span style="color: #339933;">*</span>u<span style="color: #339933;">;</span><span style="color: #009900;">&#123;</span>t<span style="color: #339933;">*</span>z<span style="color: #339933;">,*</span>v<span style="color: #339933;">,*</span>p<span style="color: #339933;">,</span>
<span style="color: #339933;">*</span>x<span style="color: #339933;">;</span>z<span style="color: #339933;">=</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">,</span>q<span style="color: #009900;">&#40;</span>z<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">=</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">,</span>v
<span style="color: #339933;">=</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">,</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>a<span style="color: #339933;">=</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>x<span style="color: #339933;">=</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>x
<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>a<span style="color: #339933;">=</span><span style="color: #0000dd;">3</span><span style="color: #339933;">,</span>x<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">=</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>p<span style="color: #339933;">=</span>x<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>p
<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>p<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>a<span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span>p<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>
v<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>h<span style="color: #009900;">&#40;</span>u<span style="color: #009900;">&#41;</span>t<span style="color: #339933;">*</span>u<span style="color: #339933;">;</span><span style="color: #009900;">&#123;</span>t<span style="color: #339933;">*</span>z<span style="color: #339933;">,*</span>v<span style="color: #339933;">,*</span>
w<span style="color: #339933;">;</span>int c<span style="color: #339933;">,</span>e<span style="color: #339933;">;</span>z<span style="color: #339933;">=</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">,</span>v<span style="color: #339933;">=</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">,</span>q<span style="color: #009900;">&#40;</span>
v<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>c<span style="color: #339933;">=</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">,</span>e<span style="color: #339933;">=</span>v<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">,</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">=</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b
<span style="color: #339933;">,</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>a<span style="color: #339933;">=</span><span style="color: #0000dd;">3</span><span style="color: #339933;">,</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">=</span>c<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span>e<span style="color: #339933;">+</span><span style="color: #0000dd;">9</span><span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;=</span>c<span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span><span style="color: #009900;">&#40;</span>
q<span style="color: #009900;">&#40;</span>z<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>e<span style="color: #339933;">=</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">,</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">+=</span>e<span style="color: #339933;">/</span>c<span style="color: #339933;">,</span>w<span style="color: #339933;">=</span>f<span style="color: #009900;">&#40;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>w<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">=</span>e<span style="color: #339933;">%</span>c<span style="color: #339933;">,</span>w<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>z<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">,</span>u<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>
w<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>y<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">=</span><span style="color: #009900;">&#123;</span>r<span style="color: #339933;">,</span>m<span style="color: #339933;">,</span>g<span style="color: #339933;">,</span>h<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span>sbrk<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>t<span style="color: #339933;">*</span>e<span style="color: #339933;">,*</span>p<span style="color: #339933;">,*</span>o<span style="color: #339933;">;</span>
o<span style="color: #339933;">=</span>f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>o<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>o<span style="color: #339933;">,</span>o<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span>e<span style="color: #339933;">=</span>f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
e<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>a<span style="color: #339933;">=</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>p<span style="color: #339933;">=</span>e<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>p<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">=</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>
p<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">=</span>o<span style="color: #339933;">,</span>q<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>e<span style="color: #339933;">=</span>e<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>write
<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;2.&quot;</span><span style="color: #339933;">,</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>for<span style="color: #009900;">&#40;</span><span style="color: #339933;">;;</span>e<span style="color: #339933;">=</span>e<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>c<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>q<span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
e<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #339933;">=</span>write<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,&amp;</span>amp<span style="color: #339933;">;</span>e<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>b<span style="color: #009900;">&#91;</span><span style="color: #ff0000;">&quot;0123456789&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
<span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>t<span style="color: #339933;">*</span>f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #b1b100;">return</span> i<span style="color: #339933;">||</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">1000</span><span style="color: #339933;">,</span>
k<span style="color: #339933;">=</span><span style="color: #009900;">&#40;</span>t<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>sbrk<span style="color: #009900;">&#40;</span>i<span style="color: #339933;">*</span><span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>t<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>k<span style="color: #339933;">+--</span>i<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>q<span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span>t<span style="color: #339933;">*</span>p<span style="color: #339933;">;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>y<span style="color: #009900;">&#91;</span>p<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>a<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>p<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Эта программа, например, вычисляет и выводит на stdout значение числа e с неограниченной точностью (точнее, ограниченной размером стека или терпением пользователя). Понятно, что нанимателям таких программистов очень не нравился подобный стиль. История умалчивает, сколько хакеров было уволено, пока, наконец, в 1984 году не был организован <a title="IOCCC" href="http://www0.us.ioccc.org/" target="_blank">IOCCC</a>, или, по-нашенски, <em>Международный Конкурс На Самую Запутанную Программу На C</em>. Это было настоящей отдушиной для недосамовыраженных профессионалов, и работодатели снова могли спать спокойно.</p>
<p style="text-align: justify;">Среди победителей IOCCC оказалось немало известных в компьютерном мире людей. Например, Дэвид Корн (создатель оболочки <a title="ksh" href="http://ru.wikipedia.org/wiki/Korn_shell" target="_blank">ksh</a>) в 1987 году стал одним из победителей с такой программой:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>unix<span style="color: #009900;">&#91;</span><span style="color: #ff0000;">&quot;<span style="color: #006699; font-weight: bold;">\021</span>%six<span style="color: #006699; font-weight: bold;">\012</span><span style="color: #006699; font-weight: bold;">\0</span>&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span>unix<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #ff0000;">&quot;have&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #ff0000;">&quot;fun&quot;</span><span style="color: #339933;">-</span><span style="color: #208080;">0x60</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p style="text-align: justify;">Основная интрига в том, что должно появиться на экране. Ничего сложно здесь нет, если помнить о том, что следующие две строки с точки зрения C идентичны:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">a <span style="color: #339933;">=</span> b<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
a <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#91;</span>b<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">Плюс еще нужно знать, что <code>unix</code> — предопределенный символ, эквивалентный 1, если использовать gcc. В этом можно убедиться с помощью следующей команды:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ touch foo.h; cpp -dM foo.h
...
#define unix 1
...</pre></div></div>

<p style="text-align: justify;">Если сложить два и два, получится, что программа выводит строку &laquo;unix&raquo;.</p>
<p style="text-align: justify;">Одна из моих любимых программ-чемпионов, написанная Марком Биггаром, выглядит так:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">P<span style="color: #339933;">;</span></pre></div></div>

<p style="text-align: justify;">Вот оно, настоящее Дао! Эта программа, в отличие от всех остальных победителей, <em>умеет делать все</em>. Ее нужно просто правильно скомпилировать. Например, можно заставить ее вывести &laquo;Hello, world&raquo;:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ cc -DP=&quot;main() { printf(\&quot;Hello, world\\n\&quot;); }&quot; -o beggar beggar.c
$ ./beggar
Hello, world</pre></div></div>

<p style="text-align: justify;">Нетрудно придумать, как научить программу делать и любые другие действия.</p>
<p style="text-align: justify;">Кстати, на этом же соревновании засветился и <a title="Ларри Уолл" href="http://ru.wikipedia.org/wiki/%D0%A3%D0%BE%D0%BB%D0%BB,_%D0%9B%D0%B0%D1%80%D1%80%D0%B8" target="_blank">Ларри Уолл</a>, написавший некую л<a title="wall.c" href="http://www0.us.ioccc.org/1987/wall.c" target="_blank">инвистическую чуду-юду</a>. Теперь понятно, откуда у Perl ноги растут. Оказывается, Уолл просто сделал язык, на котором непонятные программы писать гораздо проще, чем на C.</p>
<p style="text-align: justify;">Пожалуй, на этом праздничный пост пора завершать. На досуге можете посмотреть <a title="IOCCC Winners" href="http://www0.us.ioccc.org/years.html" target="_blank">исходники</a> других победителей IOCCC, гарантированно получите массу удовольствия.</p>
<p style="text-align: justify;">Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/09/programmers-day-and-ioccc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Смерть башоргам!</title>
		<link>http://typedef.ru/2008/09/die-bashorgm/</link>
		<comments>http://typedef.ru/2008/09/die-bashorgm/#comments</comments>
		<pubDate>Mon, 08 Sep 2008 10:21:37 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[продуктивность]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=25</guid>
		<description><![CDATA[Хотя всякие программерские хитрости и тонкости — безусловно штука полезная, но в вакууме, как известно, работают только сферические программисты (те самые, что пишут программы длиной в один байт). Реальные же люди вынуждены терпеть существование вокруг них всего остального мира в виде назойливых людей, телефонных звонков, развлекательных сайтов и хорошей погоды как раз тогда, когда на [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Хотя всякие программерские хитрости и тонкости — безусловно штука полезная, но в вакууме, как известно, работают только <em>сферические программисты</em> (те самые, что пишут программы длиной в один байт). Реальные же люди вынуждены терпеть существование вокруг них всего остального мира в виде назойливых людей, телефонных звонков, развлекательных сайтов и хорошей погоды как раз тогда, когда на работе завал. Я даже не возьмусь сказать, что больше определяет производительность программиста: профессиональный уровень или способность абстрагироваться от внешних раздражителей.</p>
<p style="text-align: justify;">Долгое время я страдал от такой вредной привычки. Когда в работе наступал ступор, например, окончание небольшого этапа или просто необходимость крепко подумать, я машинально открывал почту, потом RSS-ленту, потом новости, потом еще какой-то сайт, потом находил какую-то интересную статью&#8230; А когда возвращался к работе, оказывалась, что можно, в общем-то, уже не начинать, потому что скоро обед / конец рабочего дня / whatever. Короче говоря, продуктивность моя сильно от этого дела страдала.</p>
<p style="text-align: justify;">Общие методы тайм-менеджмента вроде <a title="Getting Things Done" href="http://upr.org.ru/Articles/GTD/Content.htm" target="_blank">GTD</a> работают замечательно только в теории. На практике очень многое зависит от личных предпочтений и того, насколько человек может <em>управлять своей волей</em>. Тотальному лентяю не поможет никакая супер-система продуктивности или дорогущий софт для планирования времени, а волевому человеку не нужны никакие костыли, чтобы переть напролом к поставленным целям. Выходит, все методики и инструменты личной эффективности выполняют две  (основные) функции:</p>
<ol>
<li><strong>подзадпинательную</strong> — мотивация на выполнение нужных действий и невыполнение ненужных;</li>
<li><strong>организационную</strong> — уже при наличии мотивации повысить эффективность выполняемых действий.</li>
</ol>
<p style="text-align: justify;">Не претендуя на звание гуру в этой области, попробую все же дать несколько советов, которые могут оказаться полезными, в частности, для разработчиков ПО. Обращаю внимание, что я описываю именно свою систему личной эффективности, которую бесполезно применять к себе дословно. Просто воспримите общие идеи.</p>
<ul>
<li>Необходимо вести <strong>список дел</strong>, которые необходимо выполнить. Позволить себе обходиться без такого списка могут только те, кто долгое время им пользовался и поняли, что способны быть эффективными и без него. Я составляю список дел на каждый день, плюс отдельные списки <em>отдаленных</em> дел и дел вообще <em>без временной привязки</em>. Каждый вечер и каждое утро я просматриваю все эти списки и формирую план действий на предстоящий день. В списке делаю  пометки, показывающие особый статус дела (срочность, контекст и т.п.).</li>
<li>Список дел должен быть в <strong>бумажном блокноте</strong>, а блокнот — всегда с собой. К этому я пришел спустя годы пользования всевозможными программами. Главное преимущество блокнота — <strong>постоянная видимость</strong>. Как только я прихожу на работу, домой или куда-либо еще, сразу выкладываю его на стол, и все задачи у меня перед глазами весь день. Даже КПК не обладает таким свойством. Кроме того, бумага обеспечивает исключительную <em>гибкость визуального представления</em>.</li>
<li>Сюда же, в блокнот, я <strong>записываю все идеи</strong>, которые пришли в голову за день. Потом мысли, достойные сохранения, в обработанном виде переносятся в другой блокнот или, например, в блог.</li>
<li>Каждая задача из списка запланированных на сегодня <strong>не должна занимать более часа</strong> (если быть точнее, то должна быть возможность выполнить задачу за один заход, без перерывов). Если задача большая, то я разделяю ее на несколько более мелких. Нет ничего хуже, чем постепенно выполняемое в течение нескольких дней дело, постоянно мозоляющее глаза своей незавершенностью.</li>
<li>Не стоит расстраиваться, если какие-то дела, запланированные на день, <strong>остались невыполненными</strong>. Это <strong>нормально</strong>. Их можно просто перенести на следующий день. Если же одна и та же задача кочует по блокноту в течение недели или даже дольше, нужно задуматься, действительно ли эту задачу <em>следует выполнять</em>.</li>
<li>Все действия, требующие <strong>менее 5 минут</strong>, должны выполняться <strong>немедленно</strong>.</li>
<li>Каждое выполняемое <strong>действие должно иметь цель</strong>. Это не значит, конечно, что нужно над каждым чихом размышлять — &laquo;А соответствует ли этот чих моим Принципам? А приближает ли он меня к моей Цели?&raquo;. До абсурда доходить не нужно, но стараться все же себя контролировать. Например, открывая браузер, надо четко представлять, <em>что именно мы хотим найти или узнать</em>. И если сумеем ответить на этот вопрос, определить еще, действительно ли нам <em>нужно</em> то, что мы хотим узнать. Неочевидное следствие из этого правила: дела из блокнота имеют преимущество над делами, там не перечисленными.</li>
<li>Перед совершением любого действия спросить себя, <strong>оправдывает ли действие затрачиваемое на него время</strong>? Можно ли это време потратить с большей пользой?</li>
<li>Не планировать на день больше, чем реально можно успеть сделать.</li>
</ul>
<p style="text-align: justify;">Эти нехитрые правила, хотя и отдают банальщиной, оказались на удивление эффективными. Конечно, это не система фундаментальных правил — при желании можно таких советов написать еще пару десятков, я просто указал, на мой взгляд, самое основное.</p>
<p style="text-align: justify;">Что касается <em>башорга</em> (в нарицательном смысле), то я избавился от привычки посещения не относящихся к делу сайтов очень просто: каждый день дописывал себе в todo-list задачу &laquo;Не ходить на развлекательные сайты&raquo;. Через неделю я избавился от этой привычки полностью.</p>
<p style="text-align: justify;">Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/09/die-bashorgm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Присваивание массивов</title>
		<link>http://typedef.ru/2008/09/copy-array/</link>
		<comments>http://typedef.ru/2008/09/copy-array/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 07:37:56 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=23</guid>
		<description><![CDATA[Каждый ребенок знает, что массивы и указатели в Си — это не одно и то же. Я обязательно посвящу этому волнующему вопросу один из будущих постов, но сейчас существенно то, что имя массива не может выступать в качестве lvalue. Попросту говоря — массиву нельзя ничего присвоить, поскольку его адрес определяется при компиляции; единственное исключение — [...]]]></description>
			<content:encoded><![CDATA[<p>Каждый ребенок знает, что массивы и указатели в Си — это не одно и то же. Я обязательно посвящу этому волнующему вопросу один из будущих постов, но сейчас существенно то, что имя массива не может выступать в качестве lvalue. Попросту говоря — массиву нельзя ничего присвоить, поскольку его адрес определяется при компиляции; единственное исключение — первоначальная инициализация, вроде такой:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">5</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Если же мы попробуем провернуть такой же фокус в дальнейшем:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>15
16
17
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">3</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> b<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
a <span style="color: #339933;">=</span> b<span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>получим по сусалам от компилятора:</p>

<div class="wp_syntax"><div class="code"><pre class="shell" style="font-family:monospace;">$ cc -o0 -g -o test test.c
test.c: In function 'main':
test.c:17: error: incompatible types in assignment</pre></div></div>

<p>Казалось бы, типы одинаковые: <code>int[3]</code>, но нет, не дают присвоить. Такой вот семантический парадокс.<br />
Но это еще не самое интересное. Самое интересное — массивы таки можно присвоить (читай — скопировать), безо всяких <code>memcpy</code>. Вот глядите:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> s_tag <span style="color: #009900;">&#123;</span><span style="color: #993333;">int</span> arr<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span> aa<span style="color: #339933;">,</span> bb<span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> i<span style="color: #339933;">;</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
    aa.<span style="color: #202020;">arr</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span>
bb <span style="color: #339933;">=</span> aa<span style="color: #339933;">;</span></pre></div></div>

<p>Все прекрасно компилируется и работает, и именно так, как предполагалось: один массив копируется в другой, цикл копирования генерируется компилятором.</p>
<p>Стоит добавить к этому, что при передаче массива в качестве аргумента функции копирование не происходит — передается только адрес. Зато если массив обернуть в структуру и передать ее по значению функции — копируется.</p>
<p>Мораль: массивы — это не совсем указатели и не совсем массивы; во избежание недоразумений необходимо учить матчасть.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/09/copy-array/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Выборочная инициализация массивов и структур</title>
		<link>http://typedef.ru/2008/08/designate-init/</link>
		<comments>http://typedef.ru/2008/08/designate-init/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 13:44:36 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=17</guid>
		<description><![CDATA[При всей своей примитивности язык C иногда преподносит приятные сюрпризы. Например, в совершенный восторг меня приводит способ инициализации структур и массивов под названием designated initializers (я предпочитаю переводить это как &#171;выборочная инициализация&#187;). Суть в том, что при инициализации переменной агрегатного типа можно явно указать, какие части структуры данных мы инициализируем, а какие &#8211; предоставляем обнулить [...]]]></description>
			<content:encoded><![CDATA[<p>При всей своей примитивности язык C иногда преподносит приятные сюрпризы. Например, в совершенный восторг меня приводит способ инициализации структур и массивов под названием designated initializers (я предпочитаю переводить это как &laquo;выборочная инициализация&raquo;). Суть в том, что при инициализации переменной агрегатного типа можно явно указать, какие части структуры данных мы инициализируем, а какие &#8211; предоставляем обнулить компилятору. Звучит немного заумно, поэтому сразу приведу пару простых примеров.</p>
<p>Выборочная инициализация массива (работает в C, но не в C++!):</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">7</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">7</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Выборочная инициализация структуры:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> a<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> b<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> c<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> s <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> .<span style="color: #202020;">a</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> .<span style="color: #202020;">c</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">2</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Нетрудно догадаться, что здесь происходит. В первом случае мы получаем массив из 8 элементов, два из которых инициализированы, а остальным присваивается 0. Со структурой еще проще: поля a и c получают значения, а поле b обнуляется. Рассмотрим примеры посложнее.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> a<span style="color: #339933;">;</span>
    <span style="color: #993333;">struct</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #993333;">char</span> c<span style="color: #339933;">;</span>
        <span style="color: #993333;">int</span>  d<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> b<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> c<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> s <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    .<span style="color: #202020;">a</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>
    .<span style="color: #202020;">b</span>.<span style="color: #202020;">d</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">3</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">static</span> <span style="color: #993333;">short</span> grid<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">8</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">6</span><span style="color: #339933;">,</span>
                             <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">4</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span>
                             <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">9</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">3</span><span style="color: #339933;">,</span>
                             <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">9</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">10</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Если первые два случая еще как-то интуитивно понятны, то последний поначалу заставляет задуматься. Здесь действует простое правило, такое же, как и при объявлении enum. По умолчанию индексы в инициализаторе начинаются с 0 и с каждым новым значением увеличиваются на единицу. Но если указать индекс явно, он становится новым значением по умолчанию. Приведенный выше пример раскрывается в следующее:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">4</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">9</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">9</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Таким образом, получим массив из 10 элементов.</p>
<p>К сожалению, из всякого правила есть исключения. C настолько гибок, что позволяет задурить самого себя. Дело в том, что разрешается инициализировать элементы массива в произвольном порядке. Как вы думаете, что произойдет при такой инициализации?</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">5</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Могу сказать сразу, что синтаксически конструкция безупречна.</p>
<p>Основная цель выборочной инициализации &#8211; повысить читабельность кода. Особенно это касается, пожалуй, многомерных массивов. Еще одно из возможных применений &#8211; создание словарей, индексированных по значению некоторых констант. Например, можно сделать словарь имен сигналов:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define SIGNAME(s) [s] = #s</span>
<span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span> <span style="color: #993333;">const</span> sigNames<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    SIGNAME<span style="color: #009900;">&#40;</span>SIGHUP<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    SIGNAME<span style="color: #009900;">&#40;</span>SIGINT<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    SIGNAME<span style="color: #009900;">&#40;</span>SIGQUIT<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    <span style="color: #808080; font-style: italic;">/* ... */</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">#undef SIGNAME</span></pre></div></div>

<p>Теперь, если численные значения идентификаторов сигналов изменятся, нам ничего не придется менять, массив сам подстроится. Это, конечно, достаточно примитивный случай, но вполне демонстрирующий идею &#8211; как можно соблюсти <a title="DRY code" href="http://en.wikipedia.org/wiki/DRY_code" target="_blank">принцип DRY</a> и сделать код более аккуратным.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/08/designate-init/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Кто здесь?</title>
		<link>http://typedef.ru/2008/08/kto-zdes/</link>
		<comments>http://typedef.ru/2008/08/kto-zdes/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 12:44:13 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[блог]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=18</guid>
		<description><![CDATA[Делать первый пост в блоге тематическим &#8211; на мой взгляд, нехорошо. Все должно иметь начало, и в данном случае это скучный и ничего не значащий текст, который (я надеюсь) будет быстро погребен под грудой будущих моих шедевров. В любом случае, первый пост &#171;ни о чем&#187; лично мне помогает настоиться на писательский лад &#8211; всегда приятнее [...]]]></description>
			<content:encoded><![CDATA[<p>Делать первый пост в блоге тематическим &#8211; на мой взгляд, нехорошо. Все должно иметь начало, и в данном случае это скучный и ничего не значащий текст, который (я надеюсь) будет быстро погребен под грудой будущих моих шедевров. В любом случае, первый пост &laquo;ни о чем&raquo; лично мне помогает настоиться на писательский лад &#8211; всегда приятнее творить нетленку, когда блог уже не пуст.</p>
<p>История возникновения блога настолько банальна, что я даже не буду об этом говорить. Придумайте что-нибудь сами.</p>
<p>Писать я здесь буду, в основном, о вещах, так или иначе связанных с программированием и computer science: языках программирования, алгоритмах, технологиях и прочей технической лабуде, которую читать будет (возможно) интересно только таким же ненормальным, как я. Порой, наверное, меня будет прорывать и на отвлеченные темы, но я все равно постараюсь компьютеры за уши притянуть.</p>
<p>Дизайн блога я намеренно сделал минималистичным &#8211; не люблю украшения, люблю функциональность. Если у кого-то есть замечания по поводу читабельности, эргономики и недостающих функций &#8211; с благодарностью выслушаю.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2008/08/kto-zdes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
