Что такое Dynamically-sized types (DSTs) в Rust ?
От: x-code  
Дата: 12.01.15 07:07
Оценка:
В анонсе заявлена такая новая фича.

В основном все ссылки ведут сюда: http://smallcultfollowing.com/babysteps/blog/2014/01/05/dst-take-5/
Также есть еще "предыдущая версия" http://smallcultfollowing.com/babysteps/blog/2013/04/30/dynamically-sized-types , один вопрос на Stackowerflow и еще пара упоминаний.

Но в результате я так и не понял — что это, в чем там фича?
Понятно что некоторые типы могут порождать объекты динамического размера. В С++ хотя-бы std::vector и std::list. Но это и так понятно и придумано уже давно.

А здесь что?
Re: Что такое Dynamically-sized types (DSTs) в Rust ?
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 12.01.15 07:59
Оценка: 82 (3) +1
Здравствуйте, x-code, Вы писали:

XC>Понятно что некоторые типы могут порождать объекты динамического размера. В С++ хотя-бы std::vector и std::list. Но это и так понятно и придумано уже давно.


XC>А здесь что?


std::vector и std::list — структуры постоянного размера (и известного при компиляции), содержащие указатели на память в куче.
Вот получаешь ты в функцию адрес чего-то. И хочешь это что-то скопировать по значению. Для этого надо знать как минимум, сколько байт копировать. Если это примитивный тип или тупл/структура, то размер компилятору известен статически, все ок. std::vector и std::list как раз такие.
А вот если это что-то описано как объект некоторого класса, и этот класс служит базовым для некоторых других, то возможно, что вместо объекта базового класса там окажется объект наследного, он может быть уже другого размера. Что там на самом деле — известно лишь в рантайме, вот и получается тип динамического размера. Если копировать, полагаясь на известный при компиляции тип, то объект может быть скопирован не целиком, получается слайсинг, беда. Поэтому в цивизизованных ОО языках все объекты размерщают в куче и передают лишь по указателю, по значению их не копируют.
Аналогично и тут, только вместо базового класса trait, который служит аналогом интерфейса. Если известен лишь интерфейс/trait, то размер объекта, который его реализует, неизвестен статически, он динамический.
Re[2]: Что такое Dynamically-sized types (DSTs) в Rust ?
От: x-code  
Дата: 12.01.15 08:29
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>А вот если это что-то описано как объект некоторого класса, и этот класс служит базовым для некоторых других, то возможно, что вместо объекта базового класса там окажется объект наследного, он может быть уже другого размера. Что там на самом деле — известно лишь в рантайме, вот и получается тип динамического размера. Если копировать, полагаясь на известный при компиляции тип, то объект может быть скопирован не целиком, получается слайсинг, беда. Поэтому в цивизизованных ОО языках все объекты размерщают в куче и передают лишь по указателю, по значению их не копируют.

DM>Аналогично и тут, только вместо базового класса trait, который служит аналогом интерфейса. Если известен лишь интерфейс/trait, то размер объекта, который его реализует, неизвестен статически, он динамический.

ОК, то есть если тип динамический (точно известен лишь в рантайме — в частности указатель на базовый класс) то и размер динамический — это понятно. Ну а фича-то в чем? Как в С++ жили без этого и почему в Rust это вдруг понадобилось?

Кстати, еще вспоминается низкоуровневая фича из Си "struct hack" — там тоже размер фактического объекта динамический и известен лишь в рантайме:
struct FOO {
  int size;
  char buf[0]; // buf[size]
};

хотел упомянуть в первом сообщении, но непонятно в тему ли это...
Отредактировано 12.01.2015 8:30 x-code . Предыдущая версия .
Re[3]: Что такое Dynamically-sized types (DSTs) в Rust ?
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 12.01.15 08:41
Оценка:
Здравствуйте, x-code, Вы писали:

XC>ОК, то есть если тип динамический (точно известен лишь в рантайме — в частности указатель на базовый класс) то и размер динамический — это понятно. Ну а фича-то в чем? Как в С++ жили без этого и почему в Rust это вдруг понадобилось?


В C++, нецивилизованном языке, жили как привыкли — компилятор ничего не обещает, все потенциальные косяки на совести программиста, пусть берет дебаггер и ищет ошибку сам. В Rust же взялись обеспечить какие-то гарантии.

XC>Кстати, еще вспоминается низкоуровневая фича из Си "struct hack" — там тоже размер фактического объекта динамический и известен лишь в рантайме:


Rust такое теперь тоже позволяет, вроде.
Re[4]: Что такое Dynamically-sized types (DSTs) в Rust ?
От: x-code  
Дата: 12.01.15 09:47
Оценка:
Здравствуйте, D. Mon, Вы писали:

DM>В C++, нецивилизованном языке, жили как привыкли — компилятор ничего не обещает, все потенциальные косяки на совести программиста, пусть берет дебаггер и ищет ошибку сам. В Rust же взялись обеспечить какие-то гарантии.


Я туплю наверное, но все-же в чем фича? Что именно они сделали и как теперь это работает?
Пока я понял только приблизительную область, к которой относится проблема и решение...
Re[5]: Что такое Dynamically-sized types (DSTs) в Rust ?
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 12.01.15 10:15
Оценка:
Здравствуйте, x-code, Вы писали:

XC> Что именно они сделали и как теперь это работает?


Я сам пока не знаю подробностей. Судя по всему, сделали для таких типов толстые указатели (содержащие второе слово — размер) и вписали в остальную систему типов, чтобы это было более-менее прозрачно.
Re[3]: Что такое Dynamically-sized types (DSTs) в Rust ?
От: night beast СССР  
Дата: 12.01.15 10:54
Оценка:
Здравствуйте, x-code, Вы писали:

XC>ОК, то есть если тип динамический (точно известен лишь в рантайме — в частности указатель на базовый класс) то и размер динамический — это понятно. Ну а фича-то в чем? Как в С++ жили без этого и почему в Rust это вдруг понадобилось?


ну это и в сях может понадобиться:
struct test {
    virtual ~test () {}
    virtual void foo () = 0;
};

struct test1 : test {
    virtual void foo () {}
};

struct test2 : test {
    virtual void foo () {}
};

struct test_factory {
    virtual int capacity ( ) = 0;
    virtual test * create ( char * buffer ) = 0;
};

template< typename Test >
struct test_factory_impl : test_factory {
    virtual int capacity ( ) { return sizeof( Test ) + 4; }
    virtual test * create ( char * buffer ) { return new(buffer) Test(); }
};

test_factory * foo ( ) {
    if ( rand() % 2 ) {
        static test_factory_impl< test1 > f1;
        return &f1;
    } else {
        static test_factory_impl< test2 > f2;
        return &f2;
    }
}

int main () {
    for ( int i = 0; i < 2; ++i ) {
        test_factory * f = foo ( );
        local_ptr<test> t = f->create( alloca( f->size( ) ) );
        t->foo( );
    }
}


не знаю, как проще написать. здесь присутствуют очевидные ограничения.
если в Rust что-то сделали что-то такое, то это неплохо.
Отредактировано 02.02.2015 20:04 night beast . Предыдущая версия .
Re[4]: Копирование виртуального объекта?
От: johny5 Новая Зеландия
Дата: 17.01.15 09:34
Оценка:
Здравствуйте, night beast, Вы писали:

Вообще, раз уж на то пошло и вся фишка тут в копировании, чтобы копировать объект динамического размера в С++ используется такой интерфейсик:

struct ICloneable
{
  ICloneable* Clone() = 0;
}

class A : ICloneable
{...};


Дальше думаю понятно. Имея указатель на базовый класс всегда можно сделать полную копию его истинного рантайм класса.
Конечно тут потребуется немного макросомагии, чтобы вставлять обязательный boilerplate код в каждый из классов наследников.
Re[5]: Копирование виртуального объекта?
От: night beast СССР  
Дата: 02.02.15 19:45
Оценка:
Здравствуйте, johny5, Вы писали:

J>Вообще, раз уж на то пошло и вся фишка тут в копировании, чтобы копировать объект динамического размера в С++ используется такой интерфейсик:


J>
J>struct ICloneable
J>


J>Дальше думаю понятно. Имея указатель на базовый класс всегда можно сделать полную копию его истинного рантайм класса.

J>Конечно тут потребуется немного макросомагии, чтобы вставлять обязательный boilerplate код в каждый из классов наследников.

не, это чуть из другой оперы.
тот пример, что я привел, позволяет создавать динамические объекты например в стеке.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.