Re[8]: ЧАСТЬ 4: синтаксический сахар, синтаксический мусор..
От: Шахтер Интернет  
Дата: 22.05.05 19:50
Оценка: +1
Здравствуйте, McSeem2, Вы писали:

MS>Здравствуйте, Шахтер, Вы писали:


Ш>>switch -- это и есть вычислимый goto. Только он мощнее. Поскольку метки могут быть непрерывным интервалом значений, в этом случае компилятор сгенерирует таблицу jam ов, или в случае, когда нет неперерывности -- двоичное дерево сравнений.


MS>Ты прав. Я тут сам запутался в своем словоблудстве. А хотел сказать нечто другое. Конструкция switch ничего не гарантирует. А хочется именно гарантированной оптимизации.


Гарантированной оптимизации язык дать не может. Он может дать только возможность оптимизации. Остальное зависит от качества компилятора.
... << RSDN@Home 1.1.3 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[9]: ЧАСТЬ 4: синтаксический сахар, синтаксический мусор..
От: McSeem2 США http://www.antigrain.com
Дата: 23.05.05 04:34
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Гарантированной оптимизации язык дать не может. Он может дать только возможность оптимизации. Остальное зависит от качества компилятора.


Именно! В том-то и беда консткукции switch/case. Кмпилятор хоть что-то должен гарантировать. Это непростой вопрос, на самом деле. Комплятор типа C++ или Java или C# должен обеспечить сложность конструкции, не более зедекларированной. То есть, например, цикл for(i=0; i<N; i++) не может превышать O(N). Ну, при условии, что i и N — базовые типы, конечно же. В любом случае, такой цикл не может быть ни O(N^2), ни O(N log N). Другое дело, что в некоторых частных случаях, компилятор имеет право сгенерировать код, сложностью O(1), например, когда N — константа. Часто он так и поступает. Но гарантии нет. То же самое со switch. Компилятор в этом случае обязан гарантировать O(N), то есть, простой линейный поиск. Он имеет право сделать таблицу с бинарным поиском, имеет право сделать таблицу прямых переходов, если это возможно. Но нет ни малейшей гарантии того, что это будет сделано. И если мне нужна именно гарантия бинарного поиска по строкам, я не использую switch хоть в том же C#. Я использую именно бинарный поиск в явном виде и динамический полиморфизм. А если бы был вычисляемый goto, можно было бы поступить гораздо проще.
Предвижу возражения. Типа надо взять и посмотреть MSIL. Но с другой стороны, на все возможные компиляторы это не распространяется! Допустим, MS C# сгенерирует как надо. А Mono сгенерирует? А какой-нибудь левый компилятор имени Сидора Колобкова сгенерирует? Вот то-то и оно.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[6]: ЧАСТЬ 4: синтаксический сахар, синтаксический мусор..
От: Трурль  
Дата: 23.05.05 05:27
Оценка: :)
Здравствуйте, McSeem2, Вы писали:

MS>Согласен с твоими выводами (нижеудалеными), но возражаю по поводу наличия в C++ типа "строка". Нет такого типа в языке.

Как же так, строки есть, а типа нету?
Re[7]: ЧАСТЬ 4: синтаксический сахар, синтаксический мусор..
От: McSeem2 США http://www.antigrain.com
Дата: 23.05.05 05:56
Оценка:
MS>>Согласен с твоими выводами (нижеудалеными), но возражаю по поводу наличия в C++ типа "строка". Нет такого типа в языке.
Т>Как же так, строки есть, а типа нету?

А что является строкой в C++?
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[8]: ЧАСТЬ 4: синтаксический сахар, синтаксический мусор..
От: VladD2 Российская Империя www.nemerle.org
Дата: 23.05.05 21:45
Оценка: :)
Здравствуйте, McSeem2, Вы писали:

MS>А что является строкой в C++?


Можно задаться еще более филосовским вопросом... Например, что есть С++?
... << RSDN@Home 1.1.4 beta 7 rev. 457>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re: Снова D: Зверёк читает мануал
От: FR  
Дата: 24.05.05 13:32
Оценка:
Можно ли в D сделать инициализацию переменных в шаблонах по умолчанию, например как перевести вот этот плюсовый код:

template <typename T>
struct Test
{
 void fill(T* begin, int n, T t = T())
  {
  }
};


на D:

struct Test(T)
{
 void fill(T* begin, int n, T t = ???????)
  {
  }

}
Re[2]: Снова D: Зверёк читает мануал
От: c-smile Канада http://terrainformatica.com
Дата: 27.05.05 07:40
Оценка:
Здравствуйте, FR, Вы писали:

FR>Можно ли в D сделать инициализацию переменных в шаблонах по умолчанию, например как перевести вот этот плюсовый код:


FR>
FR>template <typename T>
FR>struct Test
FR>{
FR> void fill(T* begin, int n, T t = T())
FR>  {
FR>  }
FR>};
FR>


FR>на D:


FR>
FR>struct Test(T)
FR>{
FR> void fill(T* begin, int n, T t = ???????)
FR>  {
FR>  }

FR>}
FR>


Начну с того что в D такой template (fill) просто не нужен, достатчно
написать по месту например так:

int* p = ...;  
p[0..n] = somevalue;


Что в общем-то будет нагляднее.

Вариант наиболее близкий к тому что тебе надо можно найти в
имплементации Dictionary в Harmonia:


class Dictionary(KEY, VALUE)
{
private:  
  uint[KEY]  map;
  VALUE      elements[];
public:

  // get symbol of element, if it does not exist
  // it will be created using ctor call
  symbol opIndex(KEY key, VALUE function(KEY k) ctor)
  {
    symbol sym = map[key];
    if( sym == 0 ) // it is not in dictionary yet
    {
      sym = cast(symbol)(elements.length + 1);
      elements.length = sym;
      elements[sym - 1] = ctor(key);
      map[ key ] = sym;
    }
    return sym;
  }

  // get symbol of element, if it does not exist
  // it will be silently created with default (init)
  // value of the VALUE type
  symbol opIndex(KEY key)
  {
    return map[key];
  }

}


Выборка из dictionary произваольно элемента:

class MyClass
{
  static MyClass create(char[]) { .... }
}

Dictionary!(char[],MyClass) dict = new Dictionary!(char[],MyClass);

MyClass inst = dict[ "hello", &MyClass.create ];


Т.е. если такого элемента нет то он будет создан с помощью "внешнего ctor".
Re[14]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: vdimas Россия  
Дата: 30.05.05 21:42
Оценка: 6 (1)
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, vdimas, Вы писали:



V>>Со всякими scope-контоллерами подобные алгоритмы не представляют трудностей, записываются "как под диктовку". В случае try-finally мы должны либо городить новый уровень вложенности на каждый №, либо усложнять блок finally, проверяя, что мы успели создать, а что нет. Получаем скорее деструктуризацию, чем структуризацию.


VD>Вот бы глянуть на подобный реальный код. А то реально деструкторы в 99% случаев память особождают...


Подобный код у нас был при загрузке удаленного файла во внутренний кеш по нашим внутренним интерфейсам.

1. Взятие потока из пула, в этом потоке далее:
2. Получение ссылки на удаленный объект — сессию закачки файла
3. Эту сессию необходимо явно "закрывать" в конце операций, ибо она держит конекшн к базе данных, откуда скачивается большой файл
4. Создание локального файла
5. Закачка очередного куска в цикле
6. Скидывание на диск, goto 3

Пункты 1-5 создают ресурсы, требующие контроля.

Автоматизируемые действия:
1 — возврат потока в пул
2 — уничтожение прокси
3 — явный вызов удаленного метода Release()
4 — удаление либо закрытие файла
5 — освобождение динамического буфера памяти

Сама закачка тоже такой из себя объект, который предоставляет информацию о текущем состоянии и принимает внешние "раздражители", и тоже, соответственно, контроллируется.

Эти внешние "раздражители" — суть объекты-команды (обрабатываются как события), которые передаются м/у потоками. Время их жизни тоже зависит от многих причин (успех/неуспех/не доехали до целевого треда ибо его больше нет и т.д.)

Итого имеем 7 ресурсов на ровном месте, требующих явного управления.

Было несколько вложенных и соседствующих try-catch, но исключительно работающих на локализацию стадии, на которой произошла ошибка, т.е. эти try-catch решали логические задачи, а не "механические", и их расположение и "охват" был соответствующий.

VD>Но ЖЦ конечно рулит. Тут ни плюся ни делифи и рядом не стояли.


И все-равно — спорный вопрос. Да, в подавляющем большинстве случаев он все-таки рулит. Особенно он рулит при контроле времени жизни объектов, используемых в нескольких потоках.

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

Так же хороша собой тактика постепенного "накопления" буферов и устаканивания самого процесса выделения памяти параметрами текущего алгоритма (неизвестными при компиляции). http://www.rsdn.ru/Forum/Message.aspx?mid=550839&amp;only=1
Автор: vdimas
Дата: 26.02.04
Re[3]: Снова D: Зверёк читает мануал
От: FR  
Дата: 17.06.05 10:49
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, FR, Вы писали:



CS>Начну с того что в D такой template (fill) просто не нужен, достатчно

CS>написать по месту например так:

fill у меня чисто для примера.


CS>Вариант наиболее близкий к тому что тебе надо можно найти в

CS>имплементации Dictionary в Harmonia:


Угу но на C++ это гораздо красивей. Вообще есть очущение что шаблоны в D не доделаны.
Я правда нашел что у встроенных типов есть свойство .init которое можно использовать для инициализации по умолчанию, но я не понял что будет для классов у которых .init не реализован? Как я понял UB.
Re[9]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: vlad_gri  
Дата: 21.06.05 12:00
Оценка:
Здравствуйте, L.C.R., Вы писали:
LCR>А вот обратная сторона медали: в Delphi невозможны умные указатели (и вообще, умные классы). Отсюда — насущная необходимость в finally, и обязательная уборка руками.

Реализация умных указателей(классов) для Delphi занимает в крайнем случае не
более 50 строк.
Re[10]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: WolfHound  
Дата: 21.06.05 12:54
Оценка:
Здравствуйте, vlad_gri, Вы писали:

LCR>>А вот обратная сторона медали: в Delphi невозможны умные указатели (и вообще, умные классы). Отсюда — насущная необходимость в finally, и обязательная уборка руками.

_>Реализация умных указателей(классов) для Delphi занимает в крайнем случае не более 50 строк.
Не верю. Код в студию.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[11]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: GlebZ Россия  
Дата: 21.06.05 13:15
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, vlad_gri, Вы писали:


LCR>>>А вот обратная сторона медали: в Delphi невозможны умные указатели (и вообще, умные классы). Отсюда — насущная необходимость в finally, и обязательная уборка руками.

_>>Реализация умных указателей(классов) для Delphi занимает в крайнем случае не более 50 строк.
WH>Не верю. Код в студию.
Наследоваться от TInterfacedObject

С уважением, Gleb.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[12]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: GlebZ Россия  
Дата: 21.06.05 13:16
Оценка:
Здравствуйте, GlebZ, Вы писали:

GZ>Наследоваться от TInterfacedObject

http://rsdn.ru/Forum/Message.aspx?mid=548545&amp;only=1
Автор: kavlad
Дата: 24.02.04


С уважением, Gleb.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[12]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: WolfHound  
Дата: 21.06.05 13:23
Оценка:
Здравствуйте, GlebZ, Вы писали:

WH>>Не верю. Код в студию.

GZ>Наследоваться от TInterfacedObject
А теперь сделай слабые ссылки. Или попробуй взять тип из чужой библиотеки который не отнаследован от TInterfacedObject...
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: GlebZ Россия  
Дата: 21.06.05 13:30
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>А теперь сделай слабые ссылки. Или попробуй взять тип из чужой библиотеки который не отнаследован от TInterfacedObject...

Дяденька, я не сварщик, я каску на стройке нашел.

Мне тоже подобные идеи не нравятся, но они есть.

С уважением, Gleb.
... << RSDN@Home 1.1.4 beta 4 rev. 358>>
Re[11]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: vlad_gri  
Дата: 21.06.05 16:02
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, vlad_gri, Вы писали:


_>>Реализация умных указателей(классов) для Delphi занимает в крайнем случае не более 50 строк.

WH>Не верю. Код в студию.

http://rsdn.ru/File/41945/AutoObjects.rar
Re[12]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: WolfHound  
Дата: 22.06.05 06:32
Оценка:
Здравствуйте, vlad_gri, Вы писали:

_>>>Реализация умных указателей(классов) для Delphi занимает в крайнем случае не более 50 строк.

WH>>Не верю. Код в студию.
_>http://rsdn.ru/File/41945/AutoObjects.rar
Что случиться если этот код
procedure TForm1.Test_Auto_MemoryClick(Sender: TObject);
var
    P   : PChar;
begin
    P := Auto_MemoryAlloc(32768).Ptr;
    StrCopy(P, 'Hello there');
    Caption := P;
end;

переписать так
procedure TForm1.Test_Auto_MemoryClick(Sender: TObject);
var
    P   : PChar;
    i   : Integer;
begin
    for i := 0 to 1000000000 do
    begin
        P := Auto_MemoryAlloc(32768).Ptr;
        StrCopy(P, 'Hello there');
        Caption := P;
    end;
end;

К томуже отсутствие типизации, накладные расходы...
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: vlad_gri  
Дата: 22.06.05 06:40
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Что случиться если этот код

WH>переписать так
WH>
WH>procedure TForm1.Test_Auto_MemoryClick(Sender: TObject);
WH>var
WH>    P   : PChar;
WH>    i   : Integer;
WH>begin
WH>    for i := 0 to 1000000000 do
WH>    begin
WH>        P := Auto_MemoryAlloc(32768).Ptr;
WH>        StrCopy(P, 'Hello there');
WH>        Caption := P;
WH>    end;
WH>end;
WH>


Закончится память, если ее недостаточно.

WH>К томуже отсутствие типизации, накладные расходы...


Отсутствие типизации присутствует
Какие накладные расходы
Re[14]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: WolfHound  
Дата: 22.06.05 06:58
Оценка:
Здравствуйте, vlad_gri, Вы писали:

_>Закончится память, если ее недостаточно.

Те всетки это ерунда, а не смартпоинтеры. Ибо в С++ в такой ситуации память не закончится(если ее конечно будет больше чем 32768).
А если там будет не память, а фаил или соеденение с БД или... то мы приедем гораздо раньше.

WH>>К томуже отсутствие типизации, накладные расходы...

_>Отсутствие типизации присутствует
Вот именно что присутствует.
procedure TForm1.Test_Auto_ObjectClick(Sender: TObject);
var
  SL:TFileStream;
begin
  SL := Auto_MemoryAlloc(32768).Ptr;
  Memo1.Lines.LoadFromStream(SL);
end;

К томуже если придется передать объект в другую функцию то придется передавать IAuto_Ptr
_>Какие накладные расходы
На создание временного объекта в хипе, на вызов виртуальных методов, на сохранение IAuto_Ptr черт знает где.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[15]: ЧАСТЬ 3: Конструкторы, деструкторы, и RAII
От: vlad_gri  
Дата: 23.06.05 11:55
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, vlad_gri, Вы писали:


_>>Закончится память, если ее недостаточно.

Это я поторопился ответить.
На самом деле все происходит так-же как и в C++ т.е. в каждом цикле память освобождается.

WH>Те всетки это ерунда, а не смартпоинтеры. Ибо в С++ в такой ситуации память не закончится(если ее конечно будет больше чем 32768).

WH>А если там будет не память, а фаил или соеденение с БД или... то мы приедем гораздо раньше.

WH>>>К томуже отсутствие типизации, накладные расходы...

_>>Отсутствие типизации присутствует
WH>Вот именно что присутствует.

WH>
WH>procedure TForm1.Test_Auto_ObjectClick(Sender: TObject);
WH>var
WH>  SL:TFileStream;
WH>begin
WH>  SL := Auto_MemoryAlloc(32768).Ptr;
WH>  Memo1.Lines.LoadFromStream(SL);
WH>end;
WH>

В одной старой книжке по Turbo Pascal есть такие строки.

Стандартный тип-указатель Pointer дает указатель, не связанный ни с каким конкретным базовым типом.
Этот тип совместим с любым другим типом-указателем....


и еще


.... ответственность за правильность использования того или иного параметра возлагается на
программиста.



WH>К томуже если придется передать объект в другую функцию то придется передавать IAuto_Ptr

Как раз этого делать вовсе не обязательно.


procedure TForm1.Test_Auto_ObjectClick(Sender: TObject);
var
  SL:TFileStream;
begin
  SL := Auto_Object(TFileStream.Create('AutoObjects.pas',fmOpenRead)).Ptr;
  // Передаем обьект SL в процедуру
  Memo1.Lines.LoadFromStream(SL);
end;


_>>Какие накладные расходы

WH>На создание временного объекта в хипе, на вызов виртуальных методов, на сохранение IAuto_Ptr черт знает где.
Каждый новый обьект занимает в хипе всего 16 байт.
Виртуальные методы вызываются только при создании и уничтожение IAuto_Ptr,
этим вполне можно пренебреч.
Что такое

черт знает где

лично я понятия не имею.

К стати реализация auto_ptr в C++ дает похожие накладные расходы.

http://rsdn.ru/File/41945/autoObj.rar
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.