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

Вниз

Всего за четыре часа совершено великое открытие ! :)   Найти похожие ветки 

 
Riply ©   (2007-03-10 04:33) [0]

Оказывается небезопасно "оверлоадить" функцию, которая может использоваться как CallBack.
Имеем следущее:
type
TCalcHash = function(const Sour: string): DWord;

function CalcStringHash(const StrID: DWord): DWord; overload;
function CalcStringHash(const Sour: string): DWord; overload;
procedure File_EnumHashStr(const FileHandle: THandle; CalcHash:   TCalcHash; pData: Pointer; List: TList);

Совсем не факт, что в File_EnumHashStr будет вызываться CalcStringHash(const Sour: string).
В моем случае вызывалась первая функция, ошибок не возникало, Hash - ы вычислялись.
Правда, потом (не скоро), при их использовании, творилось что-то из ряда вон выходящее :)
Четыре часа ушло на поиск причины отклонений результатов от нормы.


 
TUser ©   (2007-03-10 04:41) [1]

То есть вызывается первая функция, независимо от параметров? Tnx, надо будет запомнить и не влетать в такие грабли. Версия Delphi какая?


 
Riply ©   (2007-03-10 05:01) [2]

BDS 2006.


 
Anatoly Podgoretsky ©   (2007-03-10 07:53) [3]

> Riply  (10.03.2007 04:33:00)  [0]

"оверлоадить" никогда не безопасно


 
tesseract ©   (2007-03-10 10:26) [4]


> Оказывается небезопасно "оверлоадить" функцию, которая может
> использоваться как CallBack.


Ессно адрес блуждать будет.


 
DrPass ©   (2007-03-10 11:02) [5]


> Совсем не факт, что в File_EnumHashStr будет вызываться
> CalcStringHash(const Sour: string).

Логично. Там будет вызываться та функция, адрес которой ты в нее передашь. Перегрузка к этому никакого отношения не имеет.


 
isasa ©   (2007-03-10 11:15) [6]

DrPass ©   (10.03.07 11:02) [5]
Кстати, таки да.

Riply ©   (10.03.07 04:33)
Тоько ради любопытства. :)
А нельзя ли привести кусок кода, с фактическими параметрами для File_EnumHashStr.


 
Суслик ©   (2007-03-10 11:53) [7]

2автор.

Приведи полный кусок кода, который вызывает ошибку.
Если правда то, что ты говоришь, то это не просто открытие - это тривиальный баг.

Напиши воспроизводимый пример, а я его кину в репорты на http://qc.codegear.com

ТАКЖЕ, если не сложно - отпиши пример мне на timokhov@gmail.com


 
Суслик ©   (2007-03-10 11:54) [8]

вообще я активно пользуюсь подобной консрукцией - пока ни разу не влетал в проблемы.


 
DrPass ©   (2007-03-10 12:00) [9]


> Суслик ©   (10.03.07 11:53) [7]

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


 
Суслик ©   (2007-03-10 12:09) [10]


> [9] DrPass ©   (10.03.07 12:00)
>
> > Суслик ©   (10.03.07 11:53) [7]
>
> Адреса перегруженных функций вычисляются при компиляции.
> Колбек создается динамически в рантайме, когда все адреса
> уже посчитаны. Одно другого ну никак не касается. Это явный
> баг разработчика.

да я вообще не понял суть - примера кода то нет, только обрывки и эмоции :)
Пусть код напишет, если уверен, что это баг.


 
TUser ©   (2007-03-10 12:23) [11]

D7 и FreePascal2.0 (mode delphi) используют последнюю из овелоднутых функций и по-другому не хочет. Пример вызывает ошибку при компиляции (число вместо строки). Если заменить 10 на "aaa" то оба раза печатает цифирь 3.

{$apptype console}

type
TFunc = function (A: string): integer;

function Func (A: integer): integer; overload;
begin
  result := A + 1;
end;

function Func (A: string): integer; overload;
begin
  result := length (A);
end;

procedure ExecFunc (F: TFunc);
begin
  writeln (F (10));
end;

var F: TFunc;
begin
 F := Func;
 writeln (F (10));
 ExecFunc (F);
end.


 
Суслик ©   (2007-03-10 12:28) [12]


> [11] TUser ©   (10.03.07 12:23)

а у тебя это вообще компилится? не должно вроде: в процедуре ExecFunc ошибка компиляции должна быть.


 
Суслик ©   (2007-03-10 12:32) [13]

Вроде все верно работает

program Project1;
{$apptype console}
type
  TFunc = function (A: string): integer;
function Func (A: integer): integer; overload;
begin
  result := A + 1;
end;
function Func (A: string): integer; overload;
begin
  result := length (A);
end;
procedure ExecFunc (F: TFunc);
begin
  writeln (F ("2222"));
end;
begin
 ExecFunc(Func);
 ReadLn;
end.


Выдает 4, как и задумывалось.


 
Riply ©   (2007-03-10 12:33) [14]

>[5] DrPass ©   (10.03.07 11:02)
>Логично. Там будет вызываться та функция, адрес которой ты в нее передашь.
> [9] DrPass ©   (10.03.07 12:00)
>Это явный баг разработчика.
Абсолютно верно.
P.S.
Вот так всега: совершаешь великое открытие,
а потом приходиться вспоминать "Письмо ученому соседу" :)


 
Суслик ©   (2007-03-10 12:35) [15]

все, дельфи реабилитирован :)

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


 
TUser ©   (2007-03-10 12:43) [16]

> а у тебя это вообще компилится?

Нет, конесно. Я ж написал.


 
TUser ©   (2007-03-10 12:44) [17]

> все, дельфи реабилитирован :)

А ты в BDS2006 тестировал? У автора там косяк вылезает.


 
Суслик ©   (2007-03-10 12:48) [18]

именно в ней, родимой, и смотрел.

автор вроде признала, что была не права


 
Суслик ©   (2007-03-10 12:49) [19]

вообще ошибки по перегрузке очень интересны: их нужно обязательно постить в Quality Central.


 
Юрий Зотов ©   (2007-03-10 17:49) [20]

> Всего за четыре часа совершено великое открытие!

И еще 8 часов понадобилось на его закрытие.


 
Правильный Вася   (2007-03-10 18:43) [21]

а как же эксгумация через месяц?



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

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

Наверх




Память: 0.52 MB
Время: 0.033 c
15-1173038445
Romm
2007-03-04 23:00
2007.04.01
PHP и MySQL срочно!


1-1170775820
Krants
2007-02-06 18:30
2007.04.01
Прокрутка для WebBrowser


15-1173215736
ArtemESC
2007-03-07 00:15
2007.04.01
Десятичное число в строку


2-1173747390
Ref
2007-03-13 03:56
2007.04.01
Защита от копирования


3-1168230571
O.O
2007-01-08 07:29
2007.04.01
Оператор UPPER