Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
15-1173505252
Expell
2007-03-10 08:40
2007.04.01
Сторонние компоненты


15-1173095251
Calibr
2007-03-05 14:47
2007.04.01
Frame на веб-странице


2-1173103378
djnz
2007-03-05 17:02
2007.04.01
подключится к firebird из delphi


15-1173621847
прог-ист
2007-03-11 17:04
2007.04.01
кодировка


1-1170838732
Medved_
2007-02-07 11:58
2007.04.01
OpenDir





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский