LINUX.ORG.RU

Планы по выпуску GTK+ версии 3

 


1

0

В списке рассылки gtk-devel-list обсуждаются планы выпуска GTK+ версии 3. Основные подготовительные действия, которые необходимо предпринять в текущей ветке:

  • Спрятать все открытые поля структур с помощью макроса GSEAL(). В случае необходимости предоставить новые методы доступа к этим полям. Также должны быть скрыты поля-указатели "priv" на структуры, содержащие закрытые данные. Эти действия уже практически полностью проведены в репозитории git://git.imendio.com/projects/gtk+.git
  • Реализовать закрытые члены класса, что включает изменения в коде GType.
  • Объявить как deprecated публичные данные класса с помощью макроса GSEAL().
  • Поскольку не останется простого способа для доступа к полям класса, а использование g_object_[sg]et() утомительно, необходимо ввести новые методы доступа, вроде g_object_get_int(), *double(), *string() и т.д.
  • Существует множество макросов, таких как GTK_WIDGET_GET_FLAGS(), которые всегда были причиной многочисленных проблем (см. bug #69872). Необходимо реализовать нормальные методы доступа (в виде функций) и избавиться от этих макросов.
  • GtkStyle, без сомнений, самый сложный тип, нуждающийся в скрытии публичных полей, и до релиза должно быть проведено множество исследований.
  • Избавиться от всего кода, объявленного deprecated в 2.x. Это подразумевает все соответствующие виджеты и функции.
  • Удалить все поля структур из публичного API. Есть два способа достичь этого:
    a) переместить все структуры в закрытые заголовки;
    b) переместить структуры в C-файл реализации, но тогда всей библиотеке придётся использовать соответствующие методы доступа.
    Эти варианты ещё обсуждаются.
  • Отключить deprecated-код по умолчанию во флагах компиляции.
Таким образом, версия 3.0 будет готова к релизу. Все приложения, которые собираются для ветки 2.x с макросом GSEAL() и не используют deprecated-кода, будут без проблем собираться для ветки 3.x. Наверное, таким образом разработчики пытаются избежать кошмара миграции, который можно видеть на примере библиотеки Qt.

>>> Подробности

★★★★

Проверено: JB ()

Ответ на: комментарий от tailgunner

а "мабыць" - может быть, должно быть, пожалуй, вероятно.

alex_custov ★★★★★
()
Ответ на: комментарий от alex_custov

>>Принялся изучать этимологию слова "квелый"

>квёлы - гэта па-беларуску мабыць

TG судя по инфе из Приозёрска. Я знаю только один Приозёрск - в месте перетекания озера Вуокса в озеро Ладожское. Козырное место кстати.

Absurd ★★★
()
Ответ на: комментарий от Absurd

> Я знаю только один Приозёрск - в месте перетекания озера Вуокса в озеро Ладожское. Козырное место кстати.

"Приозерск" в профиле - это типа опознавательного знака :) И нет, это не о городке под Питером.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> "Приозерск" в профиле - это типа опознавательного знака :) И нет, это не о городке под Питером.

Тайный жидомассонский знак?

mv ★★★★★
()
Ответ на: комментарий от tailgunner

>> Я знаю только один Приозёрск - в месте перетекания озера Вуокса в озеро Ладожское. Козырное место кстати.

>"Приозерск" в профиле - это типа опознавательного знака :) И нет, это не о городке под Питером.

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

Absurd ★★★
()
Ответ на: комментарий от gaa

>> [я не анонимус, я www_linux_org_ru] > А я думал ты забанилсо. Перерегайся, с тобой интересно говорить.

Пароль под виндой остался... жаль аптайм прерывать :-)

anonymous
()
Ответ на: комментарий от Absurd

> А тут в ближайших ста мессагах уже намечался ЛОР-сейшен на Вуоксе с рыбалкой, шашлыками, блэкджеком и шлюхами.

Хм... а я вегетарианец, так что приемлю только классическую формлировку "с блэкджеком и шлюхами" :-)

В июне я в питере (ну типа белые ночи -- питерский брэнд, надо!), а потом ведь укачу обратно на черноморское побережье...

----------------

Щас я попробую сформулировать то, о чем говорит Абсурд, т.е. почему С++ был местами шагом НАЗАД по сравнению с С.

С достаточно демократичен. То есть С, если закрывает что-то, то предоставляет для закрытого достаточно богатое АПИ. С++ закрывает много чего, но АПИ предоставляет куцое, явно не достаточное.

Вот например в Паскале была такая конструкция

print "a=", a:3, " b=", b:5

я имею в виду двоеточие. Это именно синтаксическая конструкция, не оператор. И даже если программер полностью повторит логику print, то синтаксис он повторить не в состоянии. Паскаль здесь не демократичен.

С же имеет printf, который программист может написать сам, в точности копируя библиотечную. (Кстати -- гнутые расширения даже дают возможность компилятору проверять тип аргументов, если форматная строка статична, точно так же, как он это делает у обычного printf!!! Никакой дискриминации.)

Теперь переходим к плюсам... Плюсы добавляют в объекты виртуальных классов указатель на vtable. И для множественной диспетчеризации было бы самое то -- брать парочку этих указателей, комбинировать их и полученную комбинацию использовать как указатель на vtable для определения, какой метод (или функцию -- неважно) вызвать. Но хрен ты добьешься vtable от компилятора (т.е. на этапе компиляции)! А еще хорошо бы, что указатель на vtable был предсказуема, чтобы комбинация этих указателей была попроще.

Итак, вводя новые возможности, С++ вводит их НЕ демократично. Жри что дают, и придумывай свои костыли для множественной диспетчеризации...

Я подчеркну, что тут обсуждаю именно дельту между С и С++.

Насчет всякой там красоты и стройности отдельного взятого С -- это смахивает сильно на пенсионерские разговоры о том, что в молодости небо было голубее. Вообще-то без гнутых расширений, в т.ч. typeof, блока с возвратом значения и мультипараметрических макросов С порядочное гавно.

[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от anonymous

s/мультипараметрических макросов/макросов с переменным числом параметров/

anonymous
()
Ответ на: комментарий от gaa

>> Если бы Строуструп осилил написание хотя бы примитивных гуйков, то от многих концепций ему пришлось бы отказаться.

> Если б хоть кто-то из авторов языков осилил написание гуйков, то пришлось бы отказаться почти от всего. И то, что за более чем 20 лет существования гуйков ещё так и не написали адекватный оо-язык для их написания, говорит о многом, в т.ч. о плохой применимости оо для гуйков.

оо не плохо применимо для гуйков, а недостаточно для них. Для гуйков кроме оо еще нужно что-то типа аннотаций и/или рефлекшена.

(а что хорош и для всего только tcl/tk можешь не повторять, я думаю это уже все усвоили :-)

Кстати, весьма однородный синтаксис tcl/tk я одобряю. Но это не оправдание отстутствию статической типизации и много еще чему.

Вот написать гуек, хорошо описываемый XML файлом, не проблема на любом языке. А если тебе надо в качестве одного из виджетов иметь таблицу с неопределенным заранее числом строк (и может столбцов), каждая клетка которой содержит свой (различный для разных колонок) виджет? Че-то я подозреваю, что сразу захочется иметь конструкторы и деструкторы... и соответственно оо-расширение (inc tcl ?)

[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от Absurd

>> Ему, наверное, не нравится, что специализированные функции в этом примере являются методами третьего (левого) класса.

> А что, нет? Правила диспетчеризации должны храниться вместе с обработчиками, иначе в проекте появится класс-помойка c эклектичной revision history.

Даже если класса-помойки не будет, файла с "эклектичной revision history" не избежать. Уж это извините специфика -- наши функции или методы зависят от 2 иерархий, как ни крутись.

Но мне ближе мультифункции, чем мультиметоды. Как в D.

[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от Absurd

>>А почему хватит этого? И почему без этого обойтись нельзя было.

> Это сразу прояснило бы 80% идиом проектирования под С++. gui - asynchronous event-driven идиомы, БД - биндинги таблиц к полям объектов и кэширование, сеть - возможно вызвала бы появление RPC, сериализации и nio. Такой стресс-тест для ОО языка надо делать обязательно.

В точку. С++ неадекватен этим задачам. Поэтому из щелей повыползли всякие гнусные поделия типа жабы.

Вспомните свою практику -- ведь бывает хочется, чтобы инициализация шла в 2 этапа, т.е. был 1-й конструктор и 2-й конструктор? А?

Особенно хреново жить без виртуальных конструкторов!!!

[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от anonymous

И шаблоны не ортогональны наследованию, а местами можно сказать параллельны.

[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от anonymous

> Плюсы добавляют в объекты виртуальных классов указатель на vtable. И для множественной диспетчеризации было бы самое то -- брать парочку этих указателей, комбинировать их и полученную комбинацию использовать как указатель на vtable для определения, какой метод (или функцию -- неважно) вызвать.

Можно выразить в более понятном виде? А то parsing error.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Астероид и корабль являются наследниками вещи. Вместо С++ пишу слегка незаконный, но понятный С.

Значит у нас есть

typedef int func (int);

struct Thing { void* vtablep=4; int mass; virtual int f(int){...} };

компилятор делает *(Thing.vtable)=Thing.f;

struct SpaceShip { void* vtable=8; int mass; int velocity; virtual int f(int){...} };

компилятор делает *(SpaceShip.vtable)=SpaceShip.f;

struct Asteroid { void* vtable=12; int mass; virtual int f(int){...} };

компилятор делает *(Asteroid.vtable)=Asteroid.f;

мы определяем

int collideThingThing(int) { throw(...) } ... int collideAstAst(int) {... }

int collideAstShip(int) {... }

int collideShipAst(int) {... }

int collideShipShip(int) {... }

Нам надо int сollide( Thing* x, Thing* y, int i)

мы делаем во время компиляции *(Thing.vtable+Thing.vtable<<3)=collideThingThing; ... *(Asteroid.vtable+Asteroid.vtable<<3)=collideAstAst; ...

После это int сollide( Thing* x, Thing* y, int i) { return ( static_cast<func>( *(x.vtable+y.vtable<<3) )(i); }

Конкретный вид комбинации чисел (x.vtable+y.vtable<<3) можно и побыстрее наверно сделать.

[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от anonymous

и очевидно (x->vtable+y->vtable<<3)

а не (x.vtable+y.vtable<<3)

Но я по-быстрому старался, не код написать, а идею передать.

anonymous
()
Ответ на: комментарий от anonymous

астероиду можно радиус орбиты добавить, чтобы он чем-то от вещи отличался, или еще че-нить такое придумать, а то он точно вещь получился, я так не хотел.

anonymous
()
Ответ на: комментарий от anonymous

///  g++ -O3 -falign-functions=128 dd-nasl.cxx && ./a.out

#include <stdio.h>


typedef void (*func)(int);

static func memory[9999];

static int counter[9];

struct Thing
{
    typedef void (*func_)(Thing*, int);
    friend void collide(Thing* x, Thing* y, int i);
    int mass;
    void say(int i) { (func_(vtableptr[0]))(this,i);  }
    static void real_say(Thing* t_h_i_s, int i);
    Thing() { vtableptr = memory ; }
    protected: func* vtableptr;
};

struct Asteroid : public Thing
{
    static void real_say(Asteroid* t_h_i_s, int i);
    int radius; // а это доопределили
    Asteroid() { vtableptr = memory+1 ; }
};

struct Ship : public Thing
{
    static void real_say(Ship* t_h_i_s, int i);
    int velocity; // а это доопределили
    Ship() { vtableptr = memory+2 ; }
};



// наш эклектичный код :-)

void collideTT(int i)   { ++counter[0]; printf("exception!!!   i=%d\n",i);      }
void collideTA(int i)   { ++counter[1]; printf("exception!!!   i=%d\n",i);      }
void collideTS(int i)   { ++counter[2]; printf("exception!!!   i=%d\n",i);      }
void collideT_(int i)   { ++counter[2]; printf("exception!!!   i=%d\n",i);      }
void collideAT(int i)   { ++counter[3]; printf("exception!!!   i=%d\n",i);      }
void collideAA(int i)   { ++counter[4]; printf("collision A+A, i=%d\n",i);      }
void collideAS(int i)   { ++counter[5]; printf("collision A+S, i=%d\n",i);      }
void collideA_(int i)   { ++counter[5]; printf("collision A+S, i=%d\n",i);      }
void collideST(int i)   { ++counter[6]; printf("exception!!!   i=%d\n",i);      }
void collideSA(int i)   { ++counter[7]; printf("collision S+A, i=%d\n",i);      }
void collideSS(int i)   { ++counter[8]; printf("collision S+S, i=%d\n",i);      }


void dummy_real_say0(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_say1(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_say2(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_say3(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_say4(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_say5(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_say6(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_say7(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_say8(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_say9(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_sayA(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_sayB(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
void dummy_real_sayC(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
//void dummy_real_sayD(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
//void dummy_real_sayE(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
//void dummy_real_sayF(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
//void dummy_real_sayG(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }
//void dummy_real_sayH(Thing* t_h_i_s, int i) { printf("i am dummy i=%d\n",i); }

anonymous
()
Ответ на: комментарий от anonymous

void Thing::real_say(Thing* t_h_i_s, int i) { printf("pure virtal function call, i=%d\n",i); }
void Asteroid::real_say(Asteroid* t_h_i_s, int i) { printf("I am asteroid, and i=%d\n",i); }
void Ship::real_say(Ship* t_h_i_s, int i) { printf("I am ship, and i=%d\n",i); }


// инструментальное средство, обеспечивающее двойную диспетчеризацию, делает:
inline func combination(func x, func y) { return func(   ( (int(x)&(128+256+512))<<2 ) + int(y)   ); }
void collide( Thing* x, Thing* y, int i) { ( (combination(x->vtableptr[0],y->vtableptr[0])) ) (i); }


int main( int argc, char** argv )
{

    // компилятор делает:
    memory[0] = func(Thing::real_say);          printf("memory[0]=%d\n",memory[0]);
    memory[1] = func(Asteroid::real_say);       printf("memory[1]=%d\n",memory[1]);
    memory[2] = func(Ship::real_say);           printf("memory[2]=%d\n",memory[2]);


    func functions[9] = {
        collideTT, collideTA, collideTS,
        collideAT, collideAA, collideAS,
        collideST, collideSA, collideSS
    };

    for(int i=0; i<3; i++) {
        for( int j=0; j<3; j++) {
            if( int(combination(memory[i],memory[j])) > int(functions[3*i+j]) ) {
                printf("abort due to misaligned functions: uncomment 'dummy_real_say': i=%d j=%d %d != %d\n", i, j, int(combination(memory[i],memory[j])), functions[3*
                return 0;
            }
            if( int(combination(memory[i],memory[j])) < int(functions[3*i+j]) ) {
                printf("abort due to misaligned functions:   comment 'dummy_real_say': i=%d j=%d %d != %d\n", i, j, int(combination(memory[i],memory[j])), functions[3*
                return 0;
            }
        }
    }
void Thing::real_say(Thing* t_h_i_s, int i) { printf("pure virtal function call, i=%d\n",i); }
void Asteroid::real_say(Asteroid* t_h_i_s, int i) { printf("I am asteroid, and i=%d\n",i); }
void Ship::real_say(Ship* t_h_i_s, int i) { printf("I am ship, and i=%d\n",i); }


// инструментальное средство, обеспечивающее двойную диспетчеризацию, делает:
inline func combination(func x, func y) { return func(   ( (int(x)&(128+256+512))<<2 ) + int(y)   ); }
void collide( Thing* x, Thing* y, int i) { ( (combination(x->vtableptr[0],y->vtableptr[0])) ) (i); }


int main( int argc, char** argv )
{

    // компилятор делает:
    memory[0] = func(Thing::real_say);          printf("memory[0]=%d\n",memory[0]);
    memory[1] = func(Asteroid::real_say);       printf("memory[1]=%d\n",memory[1]);
    memory[2] = func(Ship::real_say);           printf("memory[2]=%d\n",memory[2]);


    func functions[9] = {
        collideTT, collideTA, collideTS,
        collideAT, collideAA, collideAS,
        collideST, collideSA, collideSS
    };

    for(int i=0; i<3; i++) {
        for( int j=0; j<3; j++) {
            if( int(combination(memory[i],memory[j])) > int(functions[3*i+j]) ) {
                printf("abort due to misaligned functions: uncomment 'dummy_real_say': i=%d j=%d %d != %d\n", i, j, int(combination(memory[i],memory[j])), functions[3*
                return 0;
            }
            if( int(combination(memory[i],memory[j])) < int(functions[3*i+j]) ) {
                printf("abort due to misaligned functions:   comment 'dummy_real_say': i=%d j=%d %d != %d\n", i, j, int(combination(memory[i],memory[j])), functions[3*
                return 0;
            }
        }
    }

    // наш код:

    printf("hello!\n");

    Thing* t1 = new Asteroid(); t1->say(1);
    Thing* t2 = new Ship();     t2->say(2);
    collide(t1,t1,11);
    collide(t1,t2,12);
    collide(t2,t2,22);
    collide(t2,t1,21);
    Thing* t0 = new Thing();
    collide(t1,t0,10);
    return 0;
}

anonymous
()
Ответ на: комментарий от anonymous

Одним сообщением не получилось :-(
Читать эту фигню надо с конца. При хороших звздах получите следующий выход:
memory[0]=134514432
memory[1]=134514304
memory[2]=134514176
hello!
I am asteroid, and i=1
I am ship, and i=2
collision A+A, i=11
collision A+S, i=12
collision S+S, i=22
collision S+A, i=21
exception!!! i=10

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

memory[0]=134514432
memory[1]=134514304
memory[2]=134514176
abort due to misaligned functions: uncomment 'dummy_real_say': i=0 j=0 134517504 != 134517376


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

-------------------

А теперь по сути.

// инструментальное средство, обеспечивающее двойную диспетчеризацию, делает:
inline func combination(func x, func y) { return func( ( (int(x)&(128+256+512))<<2 ) + int(y) ); }
void collide( Thing* x, Thing* y, int i) { ( (combination(x->vtableptr[0],y->vtableptr[0])) ) (i); }


У меня такое подозрение, что быстрее такой двойной диспетчеризации вообще ничего быть не может :-)

[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

> оо не плохо применимо для гуйков, а недостаточно для них. Для гуйков кроме оо еще нужно что-то типа аннотаций и/или рефлекшена.

Аннотации с рефлекшном были ещё в delphi(емнип) и первой версии winforms. Да вот что-то дельфи умер, а винформс 2 или три раза после этого переписали. Видимо, чего-то ещё не хватает.

> (а что хорош и для всего только tcl/tk можешь не повторять, я думаю это уже все усвоили :-)

Он недостаточно хорош. В т.ч. и отсутствием типизации.

> А если тебе надо в качестве одного из виджетов иметь таблицу с неопределенным заранее числом строк (и может столбцов), каждая клетка которой содержит свой (различный для разных колонок) виджет?

Это tablelist :) http://www.nemethi.de/tablelist/index.html

> Че-то я подозреваю, что сразу захочется иметь конструкторы и деструкторы... и соответственно оо-расширение (inc tcl ?)

Да хоть snit, хоть itcl. Тикль с его нестрогостью всё равно вывезет там где оо-подход станет недостаточен.

gaa ★★
()
Ответ на: комментарий от anonymous

> Вот при некотором неудобстве, конечно, в данном примере я сохранил наследование, но вместо встроенного механизма реализации виртуальных функций наметил свой, котороый (предположительно) делает двойную диспетчерезацию намного быстрей. Полноценный язык программировани, в отличие от плюсов, позволил бы мне сменить этот механизм без каких=либо неудобств

Вот это хорошая аргументированная критика. Спасибо.

gaa ★★
()
Ответ на: комментарий от anonymous

> неужели это правда не было очевидно?

Мне - нет.

> Когда я идею сказал? Ведь можно было много буков и не писать, так ведь?

Идея - множественная диспетчеризация, это понятно. Всё остальное - просто дебри. Может быть, ты и понимаешь, что ты написал, но я - нет. Вот после этой фразы:

*(Thing.vtable+Thing.vtable<<3)=collideThingThing;

у меня мозг сегфолтится. Thing.vtable - это указатель. Ты его фактически _умножаешь_ на 9 и записываешь что-то по получившемуся адресу? O_o Вообще ты как-то вольно относишься к адресам функций. Хочешь сказать, это работает?

> Полноценный язык программировани, в отличие от плюсов, позволил бы мне сменить этот механизм без каких=либо неудобств

Чтобы такое позволять, нужен высокоуровневый API/ABI, что привело бы к потере производительности. Си++ - это не CLOS. И даже в CLOS, по слухам, люди стараются не лазить глубоко в детали реализации объектной модели, ибо результаты могут быть неожиданными (aka "загадочные глюки").

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

> Даже если класса-помойки не будет, файла с "эклектичной revision history" не избежать. Уж это извините специфика -- наши функции или методы зависят от 2 иерархий, как ни крутись.

> Но мне ближе мультифункции, чем мультиметоды. Как в D.

А в D также, как в Dylan и CLOS?

Nihilist
()
Ответ на: комментарий от anonymous

> я имею в виду двоеточие. Это именно синтаксическая конструкция, не оператор. И даже если программер полностью повторит логику print, то синтаксис он повторить не в состоянии. Паскаль здесь не демократичен.

Все языки до разной степени недемократичны.

Nihilist
()
Ответ на: комментарий от anonymous

> Полноценный язык программировани, в отличие от плюсов, позволил бы мне сменить этот механизм без каких=либо неудобств

У каждого решения свои плюсы и минусы.

Nihilist
()
Ответ на: комментарий от tailgunner

>Чтобы такое позволять, нужен высокоуровневый API/ABI, что привело бы к потере производительности.

Ну да, перформанс это, возможно, важно. В .с++.moderated я видел красиво реализованную матрицу с грамотно перегруженными операторами. Однако бинарный формат всего этого дела был подогнан под перегруженный operator[]. В результате в коде который перемножает такие матрицы нет ни одного пападания в кэш нулевого уровня при выфетчивании очередного элемента. С++ эксперты сказали что перформанс это не главное, а главное - это literate programming, а кэш - это так, фигня.

Absurd ★★★
()
Ответ на: комментарий от mv

>Падение перфоманса - это неизбежная плата за каждый новый уровень абстракции.

Спасибо, просветил - я то не знал. Числогрызную часть можно и на асме с применением SSE2/3dNow! написать. Тут гибкой динамической логики не нужно.

Absurd ★★★
()
Ответ на: комментарий от mv

> Падение перфоманса - это неизбежная плата за каждый новый уровень абстракции.

Избежать можно (whole-program оптимизация), но тогда компилируется медленно

Nihilist
()
Ответ на: комментарий от Nihilist

> Избежать можно (whole-program оптимизация), но тогда компилируется медленно

Неможно. Если в компайл-тайме, например, неизвестно, какой конкретно метод надо будет вызывать в рантайме, то ничего и оптимизировано на момент компиляции не может быть. А неизвестной по той причине, что комбинация может быть изменена в рантайме.

mv ★★★★★
()
Ответ на: комментарий от tailgunner

> Вот после этой фразы: ; у меня мозг сегфолтится. Thing.vtable - это указатель. Ты его фактически _умножаешь_ на 9 и записываешь что-то по получившемуся адресу? O_o Вообще ты как-то вольно относишься к адресам функций. Хочешь сказать, это работает?

По порядку.

1. Да, я умножаю его на 9, но это в контексте примера, где указателям (а фактически смещениям) были даны маленькие значения, т.е. 4,8,12.

На будущее: когда я идею рассказываю, я рассказываю именно ее.

А вольность в обращении с указателями объясняется тем, что фактически здесь речь идет не о стандартном компиляторе, а о том, о котором я писал в смежных постах -- если бы он мог

А) предсказуемо располагать функции,

Б) вызывал вирт. функции не через один указатель, а сумму "сегмент+смещение"

можно было бы с указателелями (CО СМЕЩЕНИЯМИ КОНЕЧНО) примерно такое отмачивать.

2. __работающая__ версия в моей проге отличается слегка(а кстати она у тебя пошла?) и выглядит так:

*( t1->vtable+(t2->vtable)&(128+256+512)<<2 )

[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от tailgunner

>> Полноценный язык программировани, в отличие от плюсов, позволил бы мне сменить этот механизм без каких=либо неудобств

> Чтобы такое позволять, нужен высокоуровневый API/ABI, что привело бы к потере производительности.

Допустим, я пишу препроцессор над С++, делающий то, что я в рабочей проге показал -- вот и обошелся без API/ABI. Правда от С++ компилятора/линкера могут потребуется доп. возможности... но не на уровне потерь производительности В СКОРОСТИ, это ключевой момент.(блин! тут опять статью писать? мои утверждения не верны 100%, если понимать их буквально)

Собственно, почему я тут ошиваюсь -- обдумываю хороший "легкий компилятор и одновременно тяжелый препроцессор"

> Си++ - это не CLOS. И даже в CLOS, по слухам, люди стараются не лазить глубоко в детали реализации объектной модели, ибо результаты могут быть неожиданными (aka "загадочные глюки").

Люди правильно делают. Модель "лезешь куда хочешь" ущербна. Для копания в клосе нужны спец. программеры, которые выдавали бы новые фичи ОО-подхода в виде библиотечки, которые другие программеры юзают.

Короче, разделение труда.

anonymous
()
Ответ на: комментарий от Absurd

> С++ эксперты сказали что перформанс это не главное, а главное - это literate programming, а кэш - это так, фигня.

Вообще-то ссылку надо... а так, если на слово поверить, эксперты очень нехорошо сказали.

[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от Nihilist

>> Полноценный язык программировани, в отличие от плюсов, позволил бы мне сменить этот механизм без каких=либо неудобств

>У каждого решения свои плюсы и минусы.

Краткий ответ: "спасибо, просветил" :-)

Полный ответ: иногда для ускорения программинга часть А намертво связывают с частью Б, принебрегая модульностью. Например, механизм виртуальной диспетчеризации намертво связали с компилятором. Зачастую, это мертвую привязку можно разбить, не теряя скорости, и единственным минусом будет работа программиста. Языки программирования как раз находятся в такой ситуации, обостренной еще и тем, что программисты ими не довольный.

---------------

Когда мне будет влом, я буду только краткий ответ давать.

[я www_linx_org_ru]

anonymous
()
Ответ на: комментарий от tailgunner

> O_o Вообще ты как-то вольно относишься к адресам функций. Хочешь сказать, это работает?

Я хочу сказать, что:

СОВРЕМЕННЫЕ ЯЗЫКИ ПРОГРАММИРОВАНИЯ

ПРЕДОСТАВЛЯЮТ НЕОПРАВДАНО МАЛО ВОЗМОЖНОСТЕЙ

ДЛЯ ВЫРАЖЕНИЯ КАК НИЗКОУРОВНЕВЫХ, ТАК И ВЫСОКОУРОВНЕВЫХ ИДЕЙ,

И ЭТУ СИТУАЦИЮ МОЖНО ИЗМЕНИТЬ

И НУЖНО ИЗМЕНИТЬ.




[я www_linux_org_ru]

anonymous
()
Ответ на: комментарий от anonymous

> И ЭТУ СИТУАЦИЮ МОЖНО ИЗМЕНИТЬ

Можешь кратко объяснить, как ты собираешься ее менять? Только без использования старых терминов в новом смысле (как в случае с vtbl).

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Можешь кратко объяснить, как ты собираешься ее менять? Только без использования старых терминов в новом смысле (как в случае с vtbl).

Видимо "без использования старых терминов в новом смысле" не смогу.

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

anonymous
()
Ответ на: комментарий от anonymous

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

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

anonymous
()
Ответ на: комментарий от anonymous

Я ее компилю g++ (GCC) 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) на x86 32 bit.

Если будет другой компилятор -- очень вероятно что не прокатит.

anonymous
()
Ответ на: комментарий от anonymous

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

Я не смог понять мысль, которую ты этим предложением пытался донести. В плане простоты написания ОО-кода CLOS куда проще C++. А когда нужно написать нетривиальный OO-код, CLOS хотя бы позволяет это сделать.

mv ★★★★★
()
Ответ на: комментарий от mv

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

> Я не смог понять мысль, которую ты этим предложением пытался донести. В плане простоты написания ОО-кода CLOS куда проще C++. А когда нужно написать нетривиальный OO-код, CLOS хотя бы позволяет это сделать.

Ну хоть честно написал что не смог. Мысль была в контексте утверждения тейлганнера о том, что глубоко лезть в КЛОС люди боятся. Я сказал что правильно делают, что боятся. И не вел флейм "С++ против КЛОС".

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.