воскресенье, октября 09, 2005

Clocky

Clocky - это часы-будильник. Идея интересная. Когда его выключаешь, вместо того, чтобы дать тебе спокойно спать дальше, Clocky спрыгивает с тумбочки и начинает удирать от тебя с диким звоном. Ну и ничего не остается, кроме как его ловить, а там уже спать не захочется.
На сайте есть демка, не очень впечатляет. Убегает он как-то вяло, останавливается вечно. На сайте написано, что он убегает в поисках "места где спрятаться". Не похоже. Похоже на обычный рандом. Убегая он врезается в препятствия, даже не пытаясь их обогнуть.
Кстати, изобретательнице Clocky дали АнтиНобелевскую премию в области экономики.

суббота, октября 08, 2005

Эдсгер Дейкстра "Оператор go to вреден"

Классическая работа 1968-го года Go To Statement Considered Harmful.

"В течение нескольких лет я знаком с точкой зрения, что качество программистов это убывающая функция от плотности операторов go to в коде, который они пишут. Недавно я понял почему использование оператора go to имеет такой катастрофический эффект, и теперь я убежден, что оператор go to следует убрать из всех языков программирования "высокого уровня" (то есть из всех за исключением, возможно, машинного кода)..."

Technorati tag:

четверг, октября 06, 2005

Среда разработки Code::Blocks Studio

Code::Blocks - это кроссплатформенная, бесплатная, Open Source среда разработки. В ней есть многие приятные вещи, которые современная среда разработки обязана уметь. Class browser, code completion, фолдинг (folding).

Есть импорт воркспейсов Microsoft Visual Studio и проектов Dev-C++.
Насколько мне известно, популярная среда разработки Dev-C++ умеет работать только с GCC-компиляторами. Так же как и у Code::Blocks у них есть версия с MinGW GCC, есть версия вообще без компилятора. Но к Code::Blocks еще можно подключать другие (не обязательно GCC) компиляторы через приятный интерфейс.

Причем для разных проектов можно подключить разные компиляторы, можно для одного и того же проекта попробовать различные компиляторы. Последнее должно быть особенно удобно для тех, кто разрабатывает open source проекты, которые просто обязаны компиляться всеми более-меннее распространенными компиляторами. Плюс переход на другой компилятор можно произвести очень быстро. Выбираешь в списке другой компилятор, работаешь с ним - не понравилось? Возвращаешь все обратно, настройки все сохранились. Никаких дополнительных сред разработки скачивать не надо, привыкать к ним не надо.
Список компиляторов, с которыми умеет работать Code::Blocks:

Code::Blocks позволяет держать разные настройки по умолчанию для разных компиляторов.

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

Если работа над Code::Blocks будет продолжаться в том же духе, он сможет составить весьма достойную конкуренцию Microsoft Visual Studio. Дело в том, что не так давно Microsoft выпустила Microsoft Visual C++ Toolkit 2003, который, в том числе, содержит консольную версию своего компилятора, которые они используют в Visual Studio .NET 2003 Professional. Плохо в нем то, что он - компилятор командной строки, сколь-нибудь большой проект таким образом разрабатывать сложно, все равно нужно какое-то средство разработки. И если раньше выбора особенного не было и приходилось работать с Visual Studio, то теперь есть Code::Blocks, появился выбор.
Но у меня с ним обнаружилась одна небольшая засада. Компилятор из тулкита не понимает пробелы в именах файлов и названиях директорий. Я же люблю все инсталлировать в директорию Program Files. Поскольку Microsoft утверждает, что это точь-точь тот же компилятор, что используется в Visual Studio .NET 2003 Professional, то, я думаю, что это среда Visual Studio заключает названия директорий в кавычки прозрачно для пользователя. Что-либо переделывать мне было лень, так что скомпилять я ничего так и не скомпиляла. В багтраке Code::Blocks есть бага по этому поводу, но когда они ее поправят и поправят ли, большой вопрос.

Еще мнение о Code::Blocks:
Code::Blocks Studio

Ссылки по теме:
Free Windows Editors
Dev-C++
Microsoft Visual C++ Toolkit 2003

Technorati tag:

понедельник, октября 03, 2005

mutable и const_cast

Бывают случаи, когда строгое придерживание константности неудобно. Объект может оставаться логически константным ("logically const"), но при этом его физическая константность ("physically const") может быть нарушена. Пример: в неком классе на основании данных класса по очень сложному и долгому алгоритму считается некая величина. Хорошо бы эту величину закэшировать.

class CFoo
{
int cachedValue;
bool bCached;
...
public:
int calculate() const
{
//долгое вычисление
cachedValue = ...; //ошибка
//нельзя делать присвоение данным класса в константной функции
}
...
};
Но поскольку функция объявлена константной, присвоить что-либо данным класса нельзя. В таком случае функцию подсчета придется делать не константной, что странно. Ведь объект-то не менялся, он остался логически таким же каким и был. То, что физическая константность нарушена, что некоторые биты в нем поменяли свои значения, на логическую константность влияния не оказало. В таком случае можно сделать так:
class CFoo
{
mutable int cachedValue;
mutable bool bCached;
...
public:
int calculate() const
{
if(bCached) return cachedValue;
//долгое вычисление
cachedValue = ...; //все в порядке
bCached = true;
}
...
};
Подобное кэширование данных - это классический пример использования mutable.
mutable означает, что спецификатор const, примененный к классу, следует игнорировать. По стандарту только данные класса могут быть mutable.
Признак правильного использования mutable: если при доступе к данным через интерфейс класса все выглядит так, будто в классе ничего не менялось, то можно использовать mutable.
Еще один классический пример использования mutable - это синхронизация доступа к данным. Допустим, у нас есть класс, содержащий переменную, хранящую некоторое значение (data), и объект, отвечающий за синхронизацию доступа в многопоточных приложениях (sync_obj). Также есть две функции, отвечающие за доступ к данным: set_data и get_data. Функция get_data должна быть константной, она же не меняет данные класса, но как ей тогда залочить доступ к данным? Объявить sync_obj как mutable.
class mutable_test
{
int data;
mutable sync sync_obj;
public:

void set_data (int i)
{
sync_obj.lock ();
data = i;
sync_obj.unlock ();
}

int get_data () const
{
sync_obj.lock ();
int i = data;
sync_obj.unlock ();
return i;
}
};
Если mutable вполне законное средство убрать константность, у него есть классические применения, то const_cast - это всегда некий хак. Используется обычно с библиотеками, которые не являются const-корректными. С помощью const_cast можно убрать только const, навешанный на объект, который изначально константным не является. Пример:
int i;
const int * pi = &i;
// *pi имеет тип const int,
// но pi указывает на int, который константным не является
int* j = const_cast<int *> (pi);
Если же попробовать убрать const с объекта, который на самом деле const, результатом будет undefined behaviour.
struct Foo { int val; };

int main()
{
const Foo obj = { 1 };
const_cast<Foo *>(&obj)->val = 3; // undefined behaviour
return obj.val;
}
Ссылки по теме:
comp.lang.c++.moderated "usefulness of const_cast"
comp.lang.c++.moderated "legitimate use of const_cast"
comp.lang.c++.moderated "mutable: why it's in the language"


Technorati tag: