23.01.2006
BATанство.
Чем можно заниматься на сессии? Знаю, знаю, вариантов много. Некоторые наивные дети даже ошибочно полагают, что на сессии можно сдавать сессию. Это заблуждение, но не о том я веду речь.
Короче, из всего многообразия возможных занятий мною было выбрано несколько самых интересных, одно из которых – повышение навыка написания batch-скриптов. Задача это совсем не такая простая, как кажется непосвященным. На самом деле, изобретатель этого чудесного языка является весьма изощренным садистом, он смог минимальными усилиями обеспечить максимум наслаждения таким извращенным маньякам как я, за что ему большой респект.
Причина бесконечной радости моей сокрыта под катом этим
О вреде макросов (часть 2)
В прошлой части были рассмотрены психологические и религиозные вопросы, связанные с пагубным влиянием макросов на чистоту кода.
Но это только верхушка айсберга.
О вреде макросов (часть 1)
Не секрет, что в любом массовом языке программирования есть такой инструмент, как макроязык. Я не беру в учет De#$hi, ибо это не язык (возражения и протесты оформляйте в виде электронной петиции, отправляйте по адресу C:\Recycler. Там вас очень внимательно выслушают). В большинстве случаев макроязык призван облегчить труд программиста, помогая заменить отдельные повторяющиеся конструкции кода простой псевдо-функцией. В процессе трансляции кода программы эти псевдо-функции будут заменены на эти самые конструкции и все счастливы. По крайней мере, так утверждают разработчики компиляторов. Но так ли это на самом деле?
Детальный анализ
09.05.2005
Расплющеный препроцессор
Да, пора менять компилятор на более свежий.. Этот уже не справляется с моими дефайнами, чем сильно меня расстраивает. Пример:
| #define | WND_WIDTH | 800 |
| #define | WND_HEIGHT | 600 |
| #define | DRAW_WIDTH | WND_WIDTH – 6 |
| #define | DRAW_HEIGHT | WND_HEIGHT – 25 – 20 |
| #define | DRAW_TASKLIST_X | 4 |
| #define | DRAW_TASKLIST_W | 80 |
| #define | DRAW_PROCLIST_W | 88 |
| #define | DRAW_PROCLIST_X | DRAW_WIDTH – DRAW_PROCLIST_W – 5 |
| #define | DRAW_GRAPH_X | DRAW_TASKLIST_X + DRAW_TASKLIST_W + 4 |
| #define | DRAW_GRAPH_W | DRAW_PROCLIST_X – DRAW_GRAPH_X – 4 |
При подсчете DRAW_GRAPH_W получаем: 701 – 88 – 4 = 777 (!!!)
И это далеко не единичный случай!
Короче, я расстроен.
28.04.2005
Хищные мутанты
Пилять, ну почему мне всегда достаются баги-убийцы? Это просто звери какие-то, а не баги.. Если вылетать, так чтобы не встать, если эксепшен, так в таком анусе, куда без оли и не добраться.. А все потому, что я очень мало работал с мультитредовыми прогами и ничерта не умею предсказывать как треды будут переменную делить..
Эхх.. Мало у меня экспы..
Все, последний раз пишу прогу спонтанно, по ходу мысли. Сначала проектировать – потом кодить. А никак не проектировать по ходу кодинга.. Нафик-нафик.
20.04.2005
Магия 2
Нет, определенно, магия таки существует.
Еще вчера в коде курсового обитал злостный баг и пофиксить его никак не удавалось, ибо никак не мог я зафиксировать его и отловить. В сильном расстройстве с понурой головой пошел спать. А сегодня с утра баг обнаружен не был. То, что вчера работало неверно, сегодня работает как хотелось. Что могло произойти с багой за ночь – ума не приложу. Даже несколько жалко, он так яростно сопротивлялся фиксу, а тут куда-то исчез и стало немного скучно.
А может, у меня завелся барабашка-кодер? Или злые духи тьмы решили помочь мне, видя мои мучения? Высадку инопланетян тоже исключать нельзя…
Короче, мистика вокруг творится…
09.03.2005
Ненависть, как она есть.
Сегодня уровень моей любви к С++ возрос до такого уровня, что охота убивать людей вилкой. Но обо всем по-порядку.
Значицца, взялся я писать курсовой по управлению памятью. Начитавшись теории, бросился кодить. Препод, как всегда, не понимает истинного языка, поэтому писать придется на моем “любимом” – на Цэ. Им, видите ли, ООП надо. Есть мнение, что если я перешагну через себя и заюзаю макросы в фасме, то им все-равно не понравится. Потому что не знают граждане основ. Забыли они предков. А, как известно, программер, не знающий асма, не программер.. Но это я отвлекся.
Ну в общем, нацарапал диалог, нацарапал процедуру диалоговую и тут возник трабл. Диалог вызывается, показывается, а на внешние раздражители не реагирует вообще. Причем, не висит намертво, а просто не обрабатывает сообщения. Я перерыл кучу сорцов. На куче языков. Пришел к выводу, что все написано правильно. Вместе с олей пробежали код процедуры диалога для кучи сообщений – все нормально. Но вдруг случился казус: когда добежали до WM_PAINT, то после его обработки он пришел снова. Таким образом, окну бесконечно посылается WM_PAINT, а другие сообщения просто не доходят. Возник закономерный вопрос: почему?
Около часа медитировал, плясал с бубном, звал духов. Ничего не помогало.
Наконец, как настоящий русский программист, решил все переписать. Достал для верности код диалоговой процедуры и… И тут увидел единственное различие. У меня заголовок процедуры выглядел так:
bool CALLBACK DlgProc(…),
а в примере так:
BOOL CALLBACK DlgProc(…).
Хладнокровно заменяю bool на BOOL, компилю, запускаю. Все работает.
Медленно встаю, подхожу к окну, долго и задумчиво смотрю на небо. В голове крутятся исключительно матерные выражения.
ЗЫ: Про приведение типов я вообще молчу. Мне не понять логику человека, которому могут нравится километровые конструкции скобочек, звездочек, амперсандов, вписанные ради преобразования от одной абстракции к другой…
ЗЗЫ: Хороший язык Цэ++. Наверное. Но тот, кто его придумал – враг человечества.
22.02.2005
Лингвистическая дискриминация
Официально заявляю, что в нашем универе существует и процветает дискриминация по лингвистическому признаку.
Дело в том, что после споров и пререканий мне все-таки не удалось договориться о языке реализации курсового. Обещанный “свободный выбор” на деле был ограничен исключитеьно сями. Да, можно выбрать из блядского МФЦ, пошарпаного, и прочей херни, которую мне вера не позволяет даже шепотом сказать.
Давно перестал чувствовать что-либо, и этот эпизод не стал исключением. Но сам факт такого наебалова меня немного угнетает.
В общем, желание писать хороший и грамотный курсовой зарублено на корню. Если надо на сях – буду писать отписку троечную для галочки.
ЗЫ: извиняюсь за нецензурную брань, но слов культурных, бля, нихуя нету.
08.02.2005
Магия
Вот многие скептики утверждают, что в нашем мире не осталось магии. Законченные пессимисты возражают, что ее никогда и не было.
Но на все их выкрики и доказательства я решительно скажу “Отнюдь”. Не далее, чем сегодня утром стал свидетелем чуда, явно магического происхождения. Но обо всем в порядке очереди.
Предисловие.
Как уже многим известно, в этом семестре меня ждет курсовой по горячо любимому (это не сарказм, мне правда нравится этот аццтой
) предмету – Структуры и Алгоритмы Обработки Данных. Для тех, кто не в курсе, расскажу краткое содержание. Курсовой подразумевает работу с графами. Собственно, это все, что известно на данный момент по ядру курсового
Да это пока и не важно. Гораздо больший интерес представляет реализация граф. интерфейса или, говоря по-простому, визуализация. Необходимо сделать курсач в окошках под винду, с использованием… да, хотя, чего угодно. Хоть на директе. Хе-хе.. Но даже это не самое интересное. А интересно то, что впервые нам позволено писать курсовой на произвольном языке. В прошлом году люди писали на билдерах, дельфях, даже на мфц. Один камрад, не будем тыкать пальцем, написал на яве и через это попал в историю – уж очень преподу понравилось. Но все это не наши языки. Все они неправильные и подлежат забвению. Единственно верный язык программирования – угадайте какой? Правильно. Фортран.
Вот на нем и буду я писать курсовой. До пенсии.
Завязка.
Нет, ну, конечно, про Фортран – это я пошутил. Есесна, ассемблер. Короче, пораскинув мозгой, я бросился писать курсовой. Да, задание нам раздадут только на следующей неделе, но кого это волнует? Есть ведь еще графическая часть, которую тоже было бы неплохо сделать. Короче, забив на крики старых маразматиков, что проги пишут не с интерфейса, а с ядра, я с двойной силой ринулся кодить интерфейс, к которому позднее будет прикручено ядро.
Сначала было слово. И было оно “format”. Забавно звучит, знаю. Но в fasm’е с этой директивы проги начинаются – она задает формат выходного файла (win32 exe, dll, drv, etc..). В общем, сначала я хотел создавать окно руками, вместе с контролами. Но вовремя отрекся от этой глупой затеи – кода вагоны, а толку мало. Поэтому уверенными движениями я удалил все, что успел накодить и запустил корявый редактор ресурсов. В корявом редакторе ресурсов набросал пару диалогов, менюшку и мгновенно все это добро скомпилил. Написал кучку кода в сорце, запустил – работает. Красота. Пришло время переходить к самой веселой части: обработке юзерских действий и рисовании ножиком по живому (т.е. рисовании по окошку).
Непосредственно сабж.
Приоткрою завесу тайны над будующим видом курсача. Коварный план мой сделать так, чтобы все операции над графом можно было делать прямо мышой прямо по картинке. Но на данном этапе прогресса прога умела только рисовать кружок посередине своего окна и никак больше ни на что не реагировать. Понимаю, что от конечной цели это далеко так же, как луна от солнца, но надо же с чего-то начинать? Ну, короче, нарисовал я этот кружок и просиял от счастья. Но заметил, что музыка стала заметно лагать. Полез смотреть нагрузку проца – так и есть. Отрисовка кружочка убила проц в нули. Он сосредоточенно рисовал кружок все свободное и несвободное время. Пораскинув мозгом еще раз, я пришел к выводу, что WM_PAINT – это не наш выбор. Знающие люди сразу закричат “Отнюдь!” и будут правы. Увы, я мало работал с gdi и не знаю элементарных основ. Но по старой памяти решил сделать отрисовку по таймеру.
Роковая ошибка ![]()
Как только я воткнул таймер, сразу вмешались потусторонние силы. Темные силы, всегда мне покровительствовавшие, внезапно отвернулись от меня и первородный баг прокрался в программу. По какой-то непонятной причине при наличии таймера окно напрочь теряло текст заголовка и свой стиль. Даже размеры терялись. Но зато кружок рисовался, это да. Но, согласитесь, утешение слабое. Да и белый кружок, ради которого все затевалось, посередине избитого жизнью и изуродованого багами окна только усугублял комичность ситуации. Причем, настолько, что я минут пять под столом валялся ![]()
Вылезя из-под стола, я стал искать причину. В тот момент я еще не верил в магию…
[прошло 4 часа...]
Я ВЕРЮ В МАГИЮ!
После четырех часов поисков причина бага была обнаружена, но как ее устранить, я не представлял. Дело в том, что баг появлялся только при наличии в директории импорта функции SetTimer. Т.е. если ее убрать (только ее), то все хорошо. Если ее вернуть – все глючит. Это касается ТОЛЬКО функции SetTimer. Если ее заменить любой другой – все нормально. Причем, не имеет значения, вызывалась ли она вобще. Окно испорчено уже на стадии создания, на входе в процедуру обработки WM_INITDIALOG. И после этого кто-то скажет, что это не магия?
Так и не разобравшись где баг, я оперативно собрался и отбыл в сторону катка, где отчаянно катался и постоянно думал о баге. Как и следовало ожидать, решение пришло случайно. Однажды, товарищ решил показать класс и поехал спиной вперед, я ехал за ним (есесна, по-нормальному
) и корректировал его движение, чтобы он граждан не сбивал. Но вскоре он начал отрываться и мне пришлось набирать скорость, чтобы не отстать. В результате скорость я набрал нехилую, при этом выдохся и все-таки отстал. Понимая, что ни свернуть на такой скорости, ни, тем более, затормозить я не смогу, было решено тормозить как всегда – вылететь с поля и влететь в сугроб. Обычно, на нормальных скоростях, я успеваю сбросить скорость и мягко выкатиться на снег. Но не в этот раз. Результат – красивый прыжок через кучку снега и не менее красивое падение с кувырком и дальнейший полет до сугроба. В результате этой итерации была растревожена давно поврежденная рука и головой удалось отбить заледеневший кусок сугроба. Собрав все звезды в кучу, я осознал, что раз SetTimer в импортах так портит окружающее, то надо смотреть что там с директорией импорта. К тому же я вспомнил, что сразу за импортами идет директория ресурсов, где и лежит мое окошко. Далее последовал логичный вывод – попробовать поменять местами директорию импорта и директорию ресурсов.
Но сидя в сугробе поменять их местами – задача крайне нетривиальная, поэтому я запомнил идею и вылез из сугроба. Но нет, не поскакал домой, как, наверное, подумал иной читатель, а продолжил кататься и искать смысл жизни.
Придя домой, я перво-наперво крепко поел и только тогда решился проверить свою идею. И в этот момент силы тьмы снова обратили на меня взор и изгнали баг. Все заработало, хоть и криво. Но кривизна сия заключалась в концепции использования таймера, а не во вмешательстве потусторонних сил…
Заключение.
Вот такие чудеса иногда творятся в мире. Жива еще магия! Не всех темных и светлых колдунов сожгли на кострах инквизиции!
ЗЫ: а от таймера пришлось отказаться в пользу все того же WM_PAINT, только на сей раз я все-таки снизошел до ознакомления с примером использования и смело написал код, который не завешивает систему и при этом рисует аккуратный и ровный кружок.