<?xml version="1.0" encoding="koi8-r"?>
<rss version="2.0">
<channel>
<title>f.f.o.</title>
<link>http://add.fenster.name/</link>
<description>f.f.o.::/add</description>
<language>ru</language>
<copyright> Copyright 2010, Alexander Fenster</copyright>
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
<ttl>6000</ttl>
<lastBuildDate>Thu, 08 Jul 2010 00:35:00 +0700</lastBuildDate>
<image>
<url>http://add.fenster.name/icon.png</url>
<title>f.f.o.</title>
<link>http://add.fenster.name/</link>
<width>32</width>
<height>32</height>
</image>
<item>
<title>[757] 8 июля 2010; 0:35</title>
<link><![CDATA[http://add.fenster.name/index.html#757]]></link>
<description><![CDATA[<p>
Прочитал эту фразу в <a href="http://lenta.ru/columns/2010/06/28/names/">заметке</a> 
на Ленте, не могу не поделиться.
</p>
<blockquote>Экскаваторщик Петров немного обижен на своих родителей за то, 
что те дали ему такое странное имя &mdash; Экскаваторщик.</blockquote>
<p>Просто гениально.</p>
]]></description>
<pubDate>Thu, 08 Jul 2010 00:35:00 +0700</pubDate>
</item>
<item>
<title>[756] 5 июля 2010; 17:50</title>
<link><![CDATA[http://add.fenster.name/index.html#756]]></link>
<description><![CDATA[<p>
Сегодня начались сразу две Летних школы: <a href="http://school.iis.nsk.su">юных программистов</a> 
и школа для студентов <a href="http://software.intel.com/ru-ru/articles/summer-school-2010-main/">на работе</a>.
Начало последней ознаменовалось тем, что в бесплатных кофейных автоматах в офисе внезапно кончилась вода.
Во всех.  Давно, наверное, студенты не пили натуральный кофе.
</p>
]]></description>
<pubDate>Mon, 05 Jul 2010 17:50:00 +0700</pubDate>
</item>
<item>
<title>[755] 12 июня 2010; 0:45</title>
<link><![CDATA[http://add.fenster.name/index.html#755]]></link>
<description><![CDATA[<p>
Я впервые написал программу на &laquo;взрослом&raquo; языке программирования &mdash; Паскале &mdash;
в восьмом классе (1995 год).  До этого было только рисование в &laquo;Кенгурёнке&raquo; &mdash; тогдашнем
аналоге Logo.  Вероятно, будь у меня в то время компьютер дома &mdash; всё сложилось бы иначе, но
всё произошло так, как произошло: граница чёткого понимания того, как работает ЭВМ, для меня до сих пор 
проходит где-то между компилируемыми языками высокого уровня и тем, во что они компилируются.  
Я только примерно представляю формат объектника и исполняемого файла и я ни разу в жизни не написал 
ни единой строчки кода ни на каком языке ассемблера (хотя читать листинги, конечно, приходилось 
по разным поводам достаточно).  Я уже не говорю про устройство процессора (как там физически байтики 
бегают) &mdash; тёмный лес.  Не то чтобы я не мог во всём этом разобраться &mdash; нет, просто 
не вижу в этом особого смысла.
</p>
<p>
Честно говоря, я по этому поводу ничуть не комплексую.  Главное &mdash; осознавать, где для тебя заканчивается
знакомое и начинается неизвестное и, в частности, уметь отказываться объяснять в подробностях студентам
или кому-либо ещё то, что происходит где-то там, в глубине.  Поводов сесть в лужу на занятии
хватает всегда, лишние не нужны, поэтому фразу &laquo;настолько низкий уровень мне неинтересен&raquo; я произношу
достаточно часто и совершенно её не стесняюсь.
</p>
<p>
К сожалению, мир развивается очень быстро.  Чувствовать свою неполноценность от незнания команд
x86 наизусть я перестал ещё на первых курсах, потому что из арсенала программистов внезапно 
пропала такая вещь, как ассемблерные вставки.  С развитием веба на первый план
вышли языки ещё более высокого уровня, что, само собой, подвинуло чуть вверх &laquo;границу понимания&raquo;
у очередных начинающих.  Сейчас от таких бывших начинающих всерьёз можно услышать предложения 
начинать обучение программированию с питона или руби (большую чушь, как мне кажется, сложно себе представить).  
</p>
<p>
Я предполагаю, что через несколько лет в софтверные компании будут устраиваться программисты,
которые будут считать, что работа со строками столь же проста, как работа с числами;
что встроенные в язык регулярные выражения были всегда; что передавать данные от программы к программе,
да и вообще хранить их нужно в формате XML;
что для создания простой формочки, отсылающей данные на сервер, необходимо городить монстра с jQuery,
ведь уже сейчас лишь малая часть &laquo;веб-программистов&raquo; понимает, что на самом деле делает
браузер, и может самостоятельно &laquo;поговорить&raquo; с веб-сервером при помощи телнета.
Год назад интёрн, делавший на каком-то там ASP веб-интерфейс к некоторой тулзе, задал мне вопрос, из которого 
явно следовало, что человек совершенно не понимает, как передаются данные между браузером и HTTP-сервером 
и какими способами можно сохранить данные между подключениями: язык и среда слишком хорошо скрывают 
такие низкоуровневые вещи.
</p>
<p>
Буду краток. Индустрия в опасности.
</p>
<p>
Нужно ли объяснять, почему я очень скептически отношусь к идее замены C на какой-либо другой язык
на первом курсе?
</p>
]]></description>
<pubDate>Sat, 12 Jun 2010 00:45:00 +0700</pubDate>
</item>
<item>
<title>[754] 13 мая 2010; 15:30</title>
<link><![CDATA[http://add.fenster.name/index.html#754]]></link>
<description><![CDATA[<p>
Перед каждой зачётной неделей блог на некоторое время превращается в локальный филиал The Daily WTF.
Могу только извиниться перед нормальными людьми (не айтишниками), которые всё ещё читают меня,
потому что нельзя не описать ошибку в студенческой программе, которую я сегодня нашёл при проверке.
</p>
<p>
<a href="http://9201.fenster.name/projects.pdf">Первое задание</a> у ФИТа в этом семестре &mdash; 
сделать <code>bc</code>-подобный целочисленный (<code>int</code>) калькулятор с поддержкой переменных.
Данный конкретный студент потратил довольно много времени на поиск и устранение всех утечек памяти
и обращений за пределы массивов (чистый прогон <code>valgrind</code>'ом &mdash;
одно из требований для сдачи в этом семестре) и наконец пришёл сдавать окончательный вариант программы.
Проверяю (сразу под валгриндом) и вижу следующую странность (жирным шрифтом показан мой ввод):
</p>
<code>
<b>5-3</b><br/>
2<br/>
<b>3-5</b><br/>
<small><i>==27846== Invalid read of size 1<br/>
==27846==    at 0x80492E3: hash (vars.c:12)<br/>
==27846==    by 0x8049407: GetValue (vars.c:51)<br/>
==27846==    by 0x80490A0: main (main.c:115)<br/>
==27846==  Address 0x4194864 is 0 bytes after a block of size 4 alloc'd<br/>
==27846==    at 0x4024C4C: malloc (vg_replace_malloc.c:195)<br/>
==27846==    by 0x8049034: main (main.c:103)<br/>
==27846==<br/></i></small>
-2<br/>
</code>
<p>
Первая мысль &mdash; надо же, где же он там, интересно, работает с массивом, за пределы которого он вылазит.  
Вторая мысль &mdash; зачем в этом примере обращаться к хэш-функции: переменных же нет, от чего он считает хэш?
Дальше было долгое ковыряние кода, в процессе которого был написан примерно следующий тесткейс:
</p>
<code>
$ <b>./calc</b><br/>
6513248+1<br/>
6513249&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# простые примеры работают<br/>
<b>ab=5</b><br/>
<b>ab+1</b><br/>
6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;и переменные тоже работают,<br/>
<b>abc=55</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# но после такого присваивания<br/>
<b>6513248+1</b><br/>
55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# начинают происходить странные вещи,<br/>
<b>6513248+2</b><br/>
6513250&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# хотя всё остальное в порядке!<br/>
</code>
<p>
Дело в том, что товарищ при работе с переменными сохранял и обрабатывал не их значения, а их имена в виде
<code>char&nbsp;*</code>.  В итоге на этапе вычислений у него образовался стек из структур, содержащих <code>void&nbsp;*</code>
(которые на самом деле хранили либо <code>int&nbsp;*</code>, либо <code>char&nbsp;*</code>),
и при вычислениях и печати результата использовалась следующая логика:
</p>
<code>
if (GetValue((char *)p))<br/>
&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n", GetValue((char *)p));<br/>
else<br/>
&nbsp;&nbsp;&nbsp;&nbsp;printf("%d\n", *(int *)p);<br/>
</code>
<p>
Думаю, программирующие на C всё давно поняли и уже раскачиваются в трансе, обхватив голову руками.
Функция <code>GetValue</code> делает поиск полученной параметром строки в хэш-таблице и возвращает 0, 
если переменной с таким именем не нашлось.  В этом случае <code>p</code> рассматривается как указатель
на <code>int</code> и этот <code>int</code> и принимается за результат.
</p>
<p>
Если вы заводите переменную с именем <code>abc</code>, строка будет состоять из четырёх байт: символы
с кодами 97, 98, 99 и завершающий 0.  На little-endian машине эти четыре байта, рассмотренные как один
<code>int</code>, дадут число 97+98*256+99*256*256=6513249.  Программа от появления такого числа впадает
в транс и начинает путать его с переменной.
</p>
<p>
Объяснить ругань валгринда (вы ещё не забыли, с чего всё начиналось?) теперь проще простого.  Если мы
проверяем программу на небольших положительных числах, в старших байтах чисел будет стоять 0, о который
запнётся и остановится функция вычисления хэш-кода имени переменной.  Получив &ndash;2 (все четыре байта ненулевые),
цикл в вычислении хэш-кода пошёл дальше выделенных под <code>int</code> четырёх байт и валгринд сообщил об ошибке.
</p>
<p>
Отправил в итоге товарища гулять ещё на неделю.  Пусть код перепишет.
</p>
]]></description>
<pubDate>Thu, 13 May 2010 15:30:00 +0700</pubDate>
</item>
<item>
<title>[753] 7 мая 2010; 0:05</title>
<link><![CDATA[http://add.fenster.name/index.html#753]]></link>
<description><![CDATA[<p>
Не могу удержаться.  ФИТ, 1 курс:
</p>
<code>
a-&gt;chars = realloc(a-&gt;chars, a-&gt;memory);<br/>
if (a-&gt;chars == NULL)<br/>
{<br/>
&nbsp;&nbsp;&nbsp;&nbsp;showerror("Купи память, быдло!11", "", -1);<br/>
&nbsp;&nbsp;&nbsp;&nbsp;abort();<br/>
}<br/>
</code>
]]></description>
<pubDate>Fri, 07 May 2010 00:05:00 +0700</pubDate>
</item>
</channel></rss>
