суббота, 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 комментариев:

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

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

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

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

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

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

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

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

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

    ОтветитьУдалить
  5. С разными списками аргументов без проблем

    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. Автовывод возвращаемого значения тут по моему сильно и не нужен, хотя при желании и с этим поизвращаться :)

    ОтветитьУдалить
  6. >T opDispatch(string s, T)(T a, T b)
    >void opDispatch(string s, T)(ref T a)


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

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

    ОтветитьУдалить