Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.01.09;
Скачать: [xml.tar.bz2];

Вниз

Правила вызова 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.013 c
1-25437
MV
2003-12-23 18:05
2004.01.09
А можно ли, отловив в обработчике формы сообщение, скажем WM_PAIN


6-25485
Chips
2003-11-06 12:53
2004.01.09
чем скорость передачи по сети померять ?


1-25338
Кен
2003-12-08 06:30
2004.01.09
Как можно БЫСТРО найти в массиве одинаковые числа ?


1-25306
Мефодий
2003-12-22 22:09
2004.01.09
Эмуляция клика мыши в другой прогроамме


1-25298
Евгыш
2003-12-23 10:07
2004.01.09
OPC сервер





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский