Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.01.09;
Скачать: CL | DM;

Вниз

Правила вызова AddRef   Найти похожие ветки 

 
Тимохов ©   (2003-12-16 14:20) [0]

type
i = interface
end;

c = object(tinterfacedobject, i)
end;

procedure func1(const a:i)
begin
end;

procedure func2(a:i)
begin
end;

var
a: i;
begin
a := c.create;
func1(a);
func2(a);
end

Вопрос: почему при вызове func1 AddRef не вызывается, а при func2 вызывается? Это именно так - установлено экспериментом. Также про это написано в некоторых книгах.
Вопрос почуму именно так и где в хелпе по Д прочесть, что это должно работать именно так?


 
Dimka Maslov ©   (2003-12-16 15:08) [1]

В первом случае передаётся константа-адрес, а во втором - переменная-копия отсюда и вызов AddRef


 
Тимохов ©   (2003-12-16 15:12) [2]


> В первом случае передаётся константа-адрес, а во втором
> - переменная-копия отсюда и вызов AddRef


Высказываение до тире очевидно. А высказываение "отсюда и вызов AddRef" ни откуда явно не следует. Разве нет? Где это написано?


 
Digitman ©   (2003-12-16 15:18) [3]

не знаю уж как в Д6, но в Д5.5 утверждение


> func1 AddRef не вызывается, а при func2 вызывается


не верно : AddRef() не вызывается ни в том ни в другом случае, и это вполне объяснимо

единственный же AddRef() вызывается в дан.примере только при вызове

a := c.create;

что опять же вполне объяснимо


 
Тимохов ©   (2003-12-16 15:19) [4]

digitman
Ты успел проверить?
Странно, у меня работает именно так как я описал...


 
Digitman ©   (2003-12-16 15:23) [5]


> Тимохов © (16.12.03 15:19) [4]


разумеется, проверил


 
Digitman ©   (2003-12-16 15:25) [6]

вот реальный код, который я у себя прогнал, в Д5.5

type
i = interface
end;

c = class(tinterfacedobject, i)
end;

var
o: c;

procedure func1(const a:i);
begin
showmessage(inttostr(o.refcount)); // здесь сч-к = 1
end;

procedure func2(a:i);
begin
showmessage(inttostr(o.refcount)); // и здесь тоже сч-к = 1
end;

procedure TfrmMain.Button4Click(Sender: TObject);
var
a: i;
begin
o := c.create;
a := o;
func1(a);
func2(a);
end;


 
Тимохов ©   (2003-12-16 15:27) [7]

Digitman © (16.12.03 15:23) [5]
Ты не прав. Проверь:

type
IInt = interface
end;

TCl = class(TObject, iint)
FRefCount: Integer;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;

function TCl.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;

function TCl._AddRef: Integer;
begin
showmessage("addref "+inttostr(frefcount));
Result := InterlockedIncrement(FRefCount);
end;

function TCl._Release: Integer;
begin
showmessage("release "+inttostr(frefcount));
Result := InterlockedDecrement(FRefCount);
if Result = 0 then
Destroy;
end;

procedure func1(const i: iint);
begin
end;

procedure func2(i: iint);
begin
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i: iint;
begin
i := tcl.create();
func1(i);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i: iint;
begin
i := tcl.create();
func2(i);
end;


 
VMcL ©   (2003-12-16 15:33) [8]

>Digitman © (16.12.03 15:25) [6]

Взял Ваш код, запустил в D6 (6.240 Update Pack 2), вот что вышло:
func1 - 1
func2 - 2


 
Тимохов ©   (2003-12-16 15:33) [9]

Digitman © (16.12.03 15:25) [6]
Проверил твой пример - он говорит о том, что я прав - у меня в первом случае 1, во втором 2. Запустил ровно твой пример без переделок. Правда Д6, но по моим воспоминаниям так и в Д3 было.


 
VMcL ©   (2003-12-16 15:34) [10]

>Тимохов © (16.12.03 15:27) [7]
>Digitman © (16.12.03 15:23) [5]
>Ты не прав. Проверь...

Он же в D5 проверяет :))


 
Digitman ©   (2003-12-16 15:35) [11]

вот реальные результаты вывода сообщений, которые формируются твоим последним кодом [7] в Д5.5:

в ходе обработки 1-й кнопки :

addref 0
release 1

в ходе обработки 2-й кнопки :

addref 0
release 1


 
Тимохов ©   (2003-12-16 15:36) [12]

Все-таки вопрос интересный. В хелпе по дельфе я этого не нашел. Инфа взята из книги Эрика Хармона. Там явно на это акцентировано винимание. Причем не сказано почему именно так.


 
Тимохов ©   (2003-12-16 15:37) [13]

VMcL © (16.12.03 15:34) [10]
Замечу, что такое же поведение у меня наблюдалось в Д3 - за это отвечаю. Я вот тут подумал, может это как-то настройками компилатора регламентируется? Поищу...


 
Digitman ©   (2003-12-16 15:43) [14]


> Тимохов


скорей всего, это опциональное поведение компилятора


 
Digitman ©   (2003-12-16 15:45) [15]


> Инфа взята из книги Эрика Хармона


у меня издания от 2000 года (старенькое)
дай ссылку на раздел и/или страницу оригинала, где есть этот акцент - посмотрю что там к чему


 
Тимохов ©   (2003-12-16 15:46) [16]

Digitman © (16.12.03 15:43) [14]
Да, наверное, буду искать.
Вопрос достаточно важен для меня - интерфейсы в программе используются достаточно активно...


 
Тимохов ©   (2003-12-16 15:50) [17]

Digitman © (16.12.03 15:45) [15]
Она у меня дома. Где-то это ближе к началу было при обсуждении общих принципов работы с интерфейсами в Д без применения к ОЛЕ.
Посмотрю - скажу.


 
Digitman ©   (2003-12-16 16:05) [18]


> Тимохов


все с тобой ясно)

включи оптимизацию компилятора - получишь результат, в точности описанный мной ... и это опять же вполне объяснимо


 
Digitman ©   (2003-12-16 16:07) [19]

к сож. Хармон не упомянул об этом в том фрагменте, на который ты ссылаешься как на заостряющий внимание

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


 
Digitman ©   (2003-12-16 16:10) [20]

а по сути вопроса - Хармон прав : компилятор генерирует неявный код управления сч-ком ссылок лишь в том случае, когда интерфейс передается по значению... случаи с декларацией var и const - это случай с передачей по ссылке, а не по значению, поэтому и результат соответствующий


 
Тимохов ©   (2003-12-16 16:13) [21]

Я уже тоже понял, что это от оптимизации зависит. Пытаюсь посмотреть это в asm"е.

Вообще говоря, нехорошо это - кину я помидор в оговод Дельфи.
То, что ты говоришь, что это объяснимо не согласен - оптимизация не должна вилиять на поведение...

На самом деле я проверил, что если в func1 и func2 обращаться к интерфейсу, то будет именно так как я говорю.

В ваше примере кода, действительно, addref вызываться не будет.


 
Тимохов ©   (2003-12-16 16:14) [22]

Digitman © (16.12.03 16:10) [20]
Вот и про тоже - по сути Хармон прав. Где он интересно надыбал такую инфу, кроме как через опыт. Но опыт дело такое - сегодня так, в след. версии по другому. А хочется пользоваться декларированным поведением.


 
Digitman ©   (2003-12-16 16:15) [23]


> Вообще говоря, нехорошо это


вообще говоря, это оч даже замечательно !
не надо помидоров)

ну ты сам посуди - на кой черт нужно вызывать AddRef() , чтобы тут же вызвать _Release() ?


 
Тимохов ©   (2003-12-16 16:19) [24]

Когда я это писал, я не прорюхал еще фишку, что если в процедурах сделать обращение к интерфейсу, то не зависимо от оптимизации _AddRef будет. Поэтому я думал, что _AddRef не вызывается при оптимизации. Вот это было бы действительно нехорошо. Разве я не прав?

Одним словом вопрос остался - где явно описано обсуждемое поведение?


 
VMcL ©   (2003-12-16 18:55) [25]

>> Тимохов © (16.12.03 16:19) [24]

Не знаю поможет ли, но вот вырезка из Help:

Delphi performs no "unsafe" optimizations that require special awareness by the programmer.

З.Ы.
Думаю, что нигде нет официального описания приемов Delphi"йского оптимизатора, хотя может я и ошибаюсь.


 
Тимохов ©   (2003-12-16 19:00) [26]

VMcL © (16.12.03 18:55) [25]
Спасибо.
Скажу так - про оптимизатор зашла речь только потому, что выяснилось, что он действительно хорошо работает и в некоторых случаях делает, действительно, правильную оптимизацию.

Исходный вопрос был, повторюсь, такой: где в документации по дельфи написано, что при передаче интерфейса в метод, где параметр описан как const НЕ вызывается AddRef, а при передаче в метод, где параметр описан БЕЗ const AddRef вызывается?


 
VMcL ©   (2003-12-25 16:54) [27]

>Тимохов © (16.12.03 19:00) [26]
>>в некоторых случаях делает, действительно, правильную оптимизацию.

LOL!!!


 
Тимохов ©   (2003-12-25 17:00) [28]

Что значит "LOL!!!"?
Наверное это сленг? Просвети.



Страницы: 1 вся ветка

Текущий архив: 2004.01.09;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.017 c
1-25343
velial
2003-12-22 11:59
2004.01.09
Delphi && Excel Replace


14-25588
Maxim Vetera
2003-12-16 18:34
2004.01.09
Цвет шрифта в Word 2002 (Office XP)


3-25216
DJohn
2003-12-05 14:27
2004.01.09
Dbexpress. Стоит ли?


14-25542
Style
2003-12-18 18:57
2004.01.09
Бета-чай :))) Я плакалъ


1-25303
Oleg__
2003-12-22 20:03
2004.01.09
Панели