*** ВНИМАНИЕ: Блог переехал на другой адрес - demin.ws ***

вторник, 6 сентября 2011 г.

Типы в C++ с явным указанием размера

Наш продукт выпускается на нескольких типах UNIX и на Windows. К счастью, все релизы с этого года только 64-бит, включая Windows (Server 2008 и Studio 2010).

Увы, но наследие 32-х бит сильно мешает и засоряет код. И одна их ключевых проблем - базовые типы.

Сейчас мы пришли к выводу, что зоопарк типов надо прекращать.

Итак, правило.

Слова char, short, long, long long, __int64 по умолчанию запрещены. Их использование придется объяснить на code review. Если нужна переменная, которая логически не является смещением в памяти, и ее предельные значения с запасом укладываются в интервал от -2^31 до 2^31-1, по это просто int. Если это индекс или смещение в памяти - это size_t.

Если же нужен беззнаковый тип, или конкретный размер, то надо использовать типа из stdint.h (int8_t, uint8_t, uint16_t, int16_t, uint32_t, int64_t, uint64_t), которые аккуратно реализованы для каждой платформы в одном единственном месте.

Шаг радикальный, посмотрим как пойдет.

Кстати, как вы справляетесь вот с этим?

for (int i = 0; i < s.length(); ++i)

Убрать предупреждение о приведении size_t к int можно, изменив на:

for (size_t i = 0; i < s.length(); ++i)

Но как быть с:

for (int i = s.length(); i >= 0; --i)

Тут уже на size_t не изменить и надо внучную писать "int i = static_cast<int>(s.length())", что, конечно, плохо.

Похожая петрушка с "strlen()", также возвращающей size_t.

воскресенье, 4 сентября 2011 г.

Сравнение программ из коробки в Windows и Mac OS X

Что обычно происходит после установки Windows? Обычно начинается установка "нужных" программ, так как "родными" программами пользоваться нереально. На Маке же почти всеми программами "из коробки" можно и нужно пользоваться.

Рассмотрим некоторые.

Телнет

Windows: telnet.exe

Этой программой можно пользоваться только случайно, по несколько минут, когда ничего другого нет под рукой, а надо быстренько зайти. Если надо именно ssh, а не telnet - ставим SecureCRT или на худой конец putty. Проблема не в telnet.exe как таковой, а в реализации консоли.

Mac: благодаря нормальной консоли (табы, полноэкранный режим, масштабирование) можно просто пользоваться штатным telnet и ssh.

Просмотр картинок

Windows: штатный просмотр картинок - голимая программа. Реально хочется сразу поставить XnView или ACDSee.

Mac: Preview в сочетании с Finder (см. ниже) - удобнейшая вещь, понимающая не только картинки, но и PDF, текстовики и т.д. Для картинок есть встроенный редактор для минимального редактирования. В Windows надо открывать Paint.

Скриншоты

Windows: Можно сделать снимок либо окна, либо всего экрана. Снимок ложится в буфер обмена, откуда его надо куда-то перенести. Хочется сразу поставить, например, FastStone Capture.

Mac: встроенная система снятия снимков экрана умеет все. Можно даже делать это из командной строки.

Веб-браузер

Windows: IE - без комментариев. Нужен FF/Chrome/Opera.

Mac: Safari является одним из топовых браузеров. Хотя Chrome на Maке все еще актуален из-за синхронизации с Google, Flash и расширений.

Почта

Windows: Windows Mail (бывший Outlook Express) вполне можно использовать от лени, но Thunderbird лучше поставить.

Mac: Apple Mac (особенно 5.0 в Lion) даст фору Thunderbird'у и даже Microsoft Outlook'у (хотя надо отдать должное - Microsoft Outlook 2011 for Mac чертовски хорош).

Командная строка и скриптование

Windows: cmd.exe - без комментариев. Это не скриптование, а ёрзанье. cscript может еще как-то спасти ситуацию.

Mac: ksh/bash/csh/python/php/ruby - на выбор из коробки.

Автоматизация работы с окнами

Windows: встроенных программ для этого нет. Может через cscript можно?!

Mac: AppleScript и Automator позволяют делать почти все. Уж как минимум кнопочки на окнах нажимать можно.

Backup

Windows: вообще есть люди, реально использующие встроенную в Windows систему архивирования?

Mac: Time Machine является удобнейшей системой инкрементального бэкапа. Можно в любой папке "отмотать" время назад и вернуть файлы к нужной дате. Сохранения могут делаться локально, без внешнего накопителя, если место есть на диске, а когда накопитель появится в доступности (по USB или сети), то сохранения автоматически уходят туда.

Например, когда ноут у меня дома, то по Wifi он всегда видит NAS, и делает сохранения туда, периодически. Если у меня много изменений, то я могу подключиться кабелем, чтобы слилось быстрее. А когда ноут не дома, все накапливается локально, и по приходу домой происходит сливание. Да, заметьте, все описанное происходит автоматически, в фоне.

Словарь

Windows: нет

Mac: Приложение Dictionary интегрировано в систему и вызыватся кликом на слове или фразе почти отовсюду. Для русского языка есть словари от Лингво, правда неофициальные.

Запуск программ и документов из командной строки

Windows: В XP я использовал TypeAndRun. В Vista и 7 уже неактуально, так как в Start > Run можно набирать имя программы, и будут выводиться варианты программ и документов, доступных в системных путях. Жить можно.

Mac: Увы, но Spotlight (вызываемый по Сmd+Space) - это глобальный индекс по всему, что есть на файловой системе, обновление которого происходит каждый раз при ее изменении. Какие-либо логические "пути" тут не при чем.

Работа с файлами

Windows: Explore (Проводник). В целом с этой программой можно жить. Но лично моя программистская натура требует двух панелей в том или ином виде. Обычно это кончается FAR'ом или Total Commander'ом.

Mac: У меня есть двухпанельный менеджер файлов на Маке, muCommander. До Фара или TC, конечно, как до луны, но жить можно. Но! Поработав в Finder ("Проводник" на Маке) некоторое время, я начал замечать, что запускаю muCommander все реже и реже. Не могу точно описать почему, просто не нужно. Возможно просто из-за общей продуманности интерфейса и возможностей Finder'а.

Пока все, что волнует лично меня.

Как-то не понятно - почему Windows комплектуется столь недоразвитыми штатными средствами? Увы, часто понять это можно только поработав там, где программы "из коробки" нормальные.

P.S. Не хочу развязывать религиозные споры, но замечания с реальными проблемами и методами их решения, конечно, приветствуются.

среда, 17 августа 2011 г.

Приведение к неполному типу в C и С++

В режиме С и С++ компилируется без ошибок:

void* p = (struct this_does_not_exist *) -1;

Убираем "struct" для С++ и получаем:

cast.cpp
cast.cpp(1) : error C2065: this_does_not_exist: необъявленный идентификатор
cast.cpp(1) : error C2059: синтаксическая ошибка: )

Теперь добавляем forward declaration:

class this_does_not_exist;
void* p = (this_does_not_exist *) -1;

Тут все честно и компилируется без ошибок.

Скорое всего тут везде все по стандарту, но первый пример все-таки какой-то странный.

GCC хотя бы предупреждение выдает.

вторник, 9 августа 2011 г.

Языковые kernel и user space


Пришла мне тут в голову забавная аналогия – если человек постоянно живет или работает в стране или среде с неродным языком вокруг, то можно считать, что родной язык – это  kernel space, неродной – user space.

Сложные, связанные с использованием почти всех ресурсов вычисления происходят в kernel space – читай: когда нужно максимально точное понимание действительности, или надо изложить запутанную мысль в каскаде таких же запутанных мыслей, то это однозначно происходит на родном языке, и только в самом конце результат уходит на вывод (читай: перевод на язык среды) в user space.

Простые, бытовые вещи могут обрабатываться без перевода (на неродном языке) и по мере увеличения знаний и опыта в нем, сложность возможной обработки в user space может увеличиваться, тем самым разгружая процессор.

Есть также люди, имеющие несколько родных языков. У таких людей просто многоядерный или многопотоковый процессор и более сложное ядро, умеющее распределять задачи между двумя или более языковыми потоками (читай: языками).

Можно пойти немного дальше.

Если человек живет и работает в родной языковой среде – он работает в командном процессоре, когда входная и выходная обработка данных весьма простая. В неродной среде – это работа в сложном UI, когда данные проходят длинный путь окон, локализации и разнообразных преобразований, чтобы поспасть на обработку в kernel space и в конце быть доставленными обратно на экран (читай: во внеший мир).

пятница, 29 июля 2011 г.

Работа с правами администратора

У новичков юникса при переходе из мира доса обычно бывает желание работать всегда под рутом. Вроде так проще. Затем, после пары-тройки неосторожных rm, установок и сносов софта или игр с ядром, когда проще всю систему просто переставить, постепенно приходит понимание, что консоль рута чревата последствиями при неаккуратной работе.

А при работе с боевыми серверами, когда можно одной неверной командой остановить работу многих людей, может лучше поработать в паре, чтобы случайно не грохнуть чего.

Как говорил один мой знакомый администратор, матерый ораклоид и юниксист: "Я никогда лишний раз в root'ом не зайду, а то вдруг чего надует (ветром)".

Тут как в армии - переходишь в режим рута - встаешь смирно, одной рукой отдаешь честь (сам себе), а второй аккуратно делаешь работу. И как только все сделано, закрываешь рутовую консоль.

А если серьезно, то бывает и так: работаешь в терминале, правишь настройки машины, собираешься уже было сказать reboot, когда понимаешь, что это консоль боевого сервера, а не девелоперской машины.

Лично я все консольные сессии к важным серверам делаю с максимально неудобной цветовой гаммой, например, зеленое на красном фоне, чтобы вот так не ошибаться.

Если разобраться, в юниксе, если ты не рут, то обычно крайне сложно сделать что-то, ломающее систему, хотя работать это не мешает. И это классное чувство. Пока ты явно не сказал su или sudo, ты на 99% спокоен, так как изменить что-то за пределами домашнего каталога система не даст.

Увы, в Windows нереально работать, не будучи формально администратором, хотя в Windows 7 ситуация улучшилась. Когда я пересел с Windows XP на семерку, я стал регулярно отвечать на вопрос о том, что какая-то программа хочет сделать что-то с правами администратора (хотя мой пользователь есть администратор в понятии Windows), и лично мне это нравится. Есть какое-то минимальное ощущения контроля на тем, что кто-то больше не "размазывает" DLL'ки по системе без моего ведома, от которых ей скоро поплохеет.

воскресенье, 24 июля 2011 г.

Организация файлов на компьютере

Думаю, что у всех, кто работает с компьютером, есть какая-то стратегия организации файлов, а у программистов уж точно.

Я опишу, как сам организую файлы, в форме почти разрозненных идей-заметок. Может что-то будет полезно кому-то, и может кто-то поделится своими приемами.

На Мак я пересел недавно, и рабочий ноутбук у меня все равно на Windows 7, то большинство приемов ориентированы на Windows.

Основная цель мой структуры - минимизировать и максимально упростить бэкап и потенциальную миграцию на другой компьютер. При правильном подходе эти задачи можно решать как одну.

Все рекомендации ниже движимы именно этой целью.

Один из подходов для решения обоих задач - сделать так, чтобы все мои файлы были доступны в иерархии одного единственного каталога. "Мои" означает, что в случае переезда на другой компьютер, данные файлы должны быть перенесены (не забыты). У меня есть каталог c:\moe (этимология английского "слова" moe утеряна). Двигаясь по этому каталогу вниз, можно найти все "мои" файлы, все-все. Также важно, что в каталоге c:\moe нет мусора, которым обычно загажен My Documents (всякие проекты-примеры, создаваемые Студией без спроса, мириады прочих папок "My..." от разных программ и т.д.). То есть это чистая полезная информация без неконтролируемого мусора.

К чему такие сложности? Не секрет, что в Windows расположение некоторых файлов "по умолчанию" весьма необычно, и далеко не все программы позволяют менять их расположение. Попробуйте найти базу данных Outlook Express или Microsoft Outlook, профайлы Thunderbird'а, Chrome'а или iTunes, настройки сессий SecureCRT и т.д. Все они обычно скрываются где-то в недрах c:\Users\your_user_name. Можно тупо бэкапить этот каталог, но, опять, там уж очень много неконтролируемого г*вна.

Итак, к помощью символьных ссылок я привел все нужные каталоги к простым путям. Например:

c:\moe\db\
          outlook\..
          thunderbird\..

       profiles\
                chrome\..
                securecrt\..
                itunes\..
                skype\..

Идем далее. Последнее время я стал люто ненавидеть программы, которые сохраняют конфигурацию и настройки в реестре. Я еще могу понять, что Microsoft Office пользуется реестром из-за "глубокой интеграции" в систему. Но вот почему Far или putty до сих пор не могут просто пользоваться текстовым файлом для настроек и сохранять его в c:\Users\... - непонятно. Для таких программ у меня написан скрипт, который командой reg копирует настройки нужных веток реестра в текстовые файлы. Что такого полезного есть в настройках Far? Например, ftp/sftp сессии. У меня их около сотни, и потерять их я не хочу.

Отдельной строкой хочу отметить программы, которыми можно использоваться в portable режиме. У меня есть отдельный каталог для них, например:

c:\moe\live\
            7z-9.20\..
            hiew-8.00\..
            winrar-3.70\..
            xnview-1.98.2\..
            putty-0.60\..
            notepad++-5.9.2\..
            ...

Обычно в этом каталоге я держу небольшие программы, которые можно просто копировать без установки, и без которых некомфортно. А так - просто перенес это каталог на другую машину, и минимальный набор утилит уже есть.

Далее, каталог c:\moe\cmd. Тут лежат разные самодельные скрипты и однофайловые микро утилиты типа junction.exe. Этот каталог находится под контролем git, так как скрипты часто меняются, и хочется видеть историю изменений.

Каталог c:\moe\projects.

Тут лежит все, связанное с программированием. Иерархия этого каталога обычно одноуровневая: проект -> каталог. Одно условие (подтвержденное годами) - не использовать пробелы в именах каталогов. Сильно упрощает скриптование.

Например, c:\moe\projects\easy-coding\.

Также полезно сделать линк каталога c:\Program Files\ в c:\prg. Проще работать в скриптах с программами, установленными в этом каталоге.

Еще один каталог - c:\moe\documents.

Тут лежат то, что называется документами, без привязки к какому-то проекту: doc(x), xls(x), pdf, jpg и т.д. Тут уже допустимы имена с пробелами и русским буквами. Внутренняя иерархия - по смыслу. С документами на работе я часто создают подкаталоги в номером года. В них удобно убирать старье. Например:

c:\moe\documents\Team meetings\
                               2010\... <- Прошлый год
                               ...      <- Нынешняя текучка

Некоторое время назад я начал активно пользоваться атрибутом read-only. Если я вижу, что не меняю файл некоторое время, например, пару месяцев, то я делаю его read-only. Это относится и к проектам и к документам. Атрибут read-only позволяет исключить случайную перезапись старого файла, открытого для получения "примера" из прошлого. Ну а уж если захочется его таки изменить, то надо будет снимать флаг read-only или делать копию через "Save as...". Основная идея - старый файл не надо перезаписывать, так как история его создания может быть подзабыта, и можно случайно похерить важный файл. Все его производные должны быть сделаны через клонирование.

Кстати, в Mac OS Lion компания Apple сделала функцию "залочки" файлов, которые не менялись некоторое время.

Documents will also automatically be locked if they're not modified for a little while. The auto-lock time is configurable in the "Options…" screen of the Time Machine preference pane (of all places), with values from one day to one year. The default is two weeks.

Есть еще несколько каталогов:

  • c:\moe\books - книги
  • c:\moe\itunes - база данных iTunes
  • c:\moe\soft - архив программ (обычно дистрибутивы)
  • c:\moe\vm - виртуальные машины

Теперь финальный шаг - осуществление бэкапа. Мой бэкап не совсем "правильный", так как он не содержит историю изменений, но зато он является моментальным снимком всех "моих" файлов. В случае проблемы или переезда на другой компьютер, я могу использовать бэкап как точную копию файловой системы и восстановить ее простым копированием. Кстати, это один из аргументов за аккуратное отделение "моих" файлов от прочего мусора.

Для физического осуществление бэкапа я использую nnbackup. Это весьма продвинутая программа, но я использую в ней только одну функцию односторонней синхронизации - при очередном сохранении каждый файл в каталоге c:\moe, который изменился, будет обновлен. Но выходе, еще раз, точная копия этого каталога на страховочном носителе.

Под занавес, для редактирования переменных окружения в Windows я использую RapidEE. Сложно представить удобнее программу.

P.S. Дополнительный довесок (чтобы два раза не вставать), который вроде бы как по теме, но не совсем. В той же статье про Lion описывается, что Apple ввели понятие версионности документов на уровне API. Я видел похожее в одной из систем разработки в Блумберге - в IDE не надо было принудительно сохранять файлы проекта. В любой момент времени среда обеспечивает сохранность файлов, и в случае зависания или прочих проблем при перезапуске открытые файлы автоматически восстанавливались из autosave'а. А вот если разработчик принудительно сохраняет файл (например, нажимает Ctrl-S), то файл не просто сохраняется, а делается commit в SVN с новой ревизией, и также приходится вводить описание этого изменения.

Сначала меня такой подход бесил, так как многолетняя привычка в досовских "массировать" F2 или Ctrl-S каждые три секунды, приводила к окну ввода описания изменений. Но со временем, я реально подсел на это. Теперь Сохранение приобрело смысл, а не было лишь средством спасения от зависания в процесса запуска.

Я был приятно удивен, то в Lion схожий подход введен на уровне операционной системы. Тут, конечно, у Apple основная цель немного иная - они хотят тем самым полностью избавиться от вопросов о сохранении несохраненных документов при выходе из приложения, чтобы их (приложения), можно было незаметно для пользователя убивать и перезапускать заново, как в iOS. Забавно, что в Lion по умолчанию в Dock'е убрали индикатор запущенности приложения. Основной посыл такой - пользователя этот вопрос более не должен волновать. Операционная система запустит приложение, если требуется, и сама убьет его, если есть потребность в его ресурсах. Документы же, всегда будут в сохранности.

Кто еще поделится идеями и приемами организации файлов?

воскресенье, 17 июля 2011 г.

Переписывать или не переписывать

Уже не помню, где я взял эту картинку, но храню ее уже давно. Это великолепная иллюстрация процесса создания программного обеспечения.


Как там у Шекспира: "переписывать или не переписывать - вот в чем вопрос". Можно приляпывать временные костыли там и сям, не давая зданию упасть, но придет время, когда законы физики возьмут свое, и здание таки нае*нется.

А можно на время вывести здание из эксплуатации и перестроить заново, например из кирпича.