Форум: "Прочее";
Текущий архив: 2007.04.01;
Скачать: [xml.tar.bz2];
ВнизВсего за четыре часа совершено великое открытие ! :) Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.036 c