суббота, 5 декабря 2009 г.

[comp.prog.bugs] Вальтер Брайт исправил баг, которому более 18 лет

Сегодня вышли новые версии компиляторов DMD – 1.053 и 2.047. В новых версиях большое количество баг-фиксов. Среди которых и исправление бага 3521. В news-группе digitalmars.D.announce Вальтер Брайт сказал, что этот баг, вероятно, прожил более 18 лет. Он срабатывал очень и очень редко. И для его поимки пришлось модифицировать C++ компилятор и прогнать большое количество тестов.

Такие дела. Что-то в последнее время баги вокруг возникают просто в невообразимых количествах. То на бажную обертку для libcurl наткнешься, то на баги в Poco. Наш новый клиент буквально вчера нашел у меня баг, которому если не пять лет, то года четыре точно. Прямо эпидемия какая-то, сезонная ;)

PS. Забавно, что в DMD 2.047 опять появилось много нововведений. В частности, некий opDispatch, назначение которого я с ходу понять не смог.

7 комментариев:

Rustam комментирует...

Да похоже до релиза D еще далеко :(

opDispatch как я понял перехват не найденных вызовов, подобное есть например в питоне, удобно чтобы делать всяческие прокси классы и для некоторых DSL.

eao197 комментирует...

>удобно чтобы делать всяческие прокси классы и для некоторых DSL.

Разработчикам D не мешало бы в документации пару-тройку жизненных примеров для этого дела привести. А то это штука такая, которая вроде как в compile-time работает, но выглядит как вызов метода. Пример же когда opDispatch приводит к определению enum-а вообще бошку сносит :) Куда его в жизни применить сразу и не поймешь.

Rustam комментирует...

Ну я в питоне подобным пользовался поэтому ничего крышесносного не вижу :)

В compile-time организовать тоже ничего сложного, если метод не найден попробовать вместо него подставить вызов шаблонной функции opDispatch.

Применений много, например прокси, притом не как operotor-> в С++ (или opDot в D) а гораздо более гибкий, например можно реализовать ленивые вычисления, или к примеру прозрачный доступ к DOM подобным конструкциям, когда можно писать типа xml.body.header = "Test". Ну и что-то linq подобное наверно будет проще сделать.

eao197 комментирует...

Ну в Ruby я тоже пользовался method_missing временами. Однако там все просто -- язык динамический и все такое.

Здесь же ситуация какая-то странная. Например, как перехватывать несколько вызовов с разными списками аргументов? Как выводить типы возвращаемых значений? В Ruby с этим проблем нет.

Rustam комментирует...

С разными списками аргументов без проблем

import std.stdio;

struct S
{
T opDispatch(string s, T)(T a, T b)
{
writefln("S.opDispatch('%s')", s);

static if(s == "add")
{
return a + b;
}

else static assert(!"unknown operator");
}

void opDispatch(string s, T)(ref T a)
{
writefln("S.opDispatch('%s')", s);

static if(s == "add")
{
++a;
}

else static assert(!"unknown operator");
}

}


void main()
{
S s;

writefln("%d", s.add(1, 2));

int x = 0;

s.add(x);

writefln("%d", x);
}


Обычная перегрузка, ну и при необходимости variadic template. Автовывод возвращаемого значения тут по моему сильно и не нужен, хотя при желании и с этим поизвращаться :)

eao197 комментирует...

>T opDispatch(string s, T)(T a, T b)
>void opDispatch(string s, T)(ref T a)


Я не знал, что в рамках одной структуры можно определить несколько opDispatch с разными параметрами.

Rustam комментирует...

Даже если бы было нельзя хватило бы variadic template + static if.