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

Вниз

Неправильно вычисляется лог.выражение   Найти похожие ветки 

 
vlk32   (2011-10-04 13:59) [0]

Есть такой вот код

class function TArrayUtils<T>.ValidParams(const Arr:array of T; const A,B,C:Integer; const CMP:TCmpFunc<T>):Boolean;
 var L : Integer;
 begin
  L := Length(Arr);
  Result :=
   (L>=2) and               // array must contain at least 2 elements
   (C>=0) and (C<=L) and    // count of used item must be in [0..L]
   (A<B) and                // A must be less than B
   (A>=0) and (B<=C-1) and  // work subarray must be in [0..C-1]
   Assigned(CMP);           // compare function must be assigned
 end;


Во время вызова функции CMP=Nil Выделяю "Assigned(CMP)" показывает что равно False, смотрю в диалоге Evaluate, тоже равно False.

Функция возвращает True. В чем загвоздка?


 
Cobalt ©   (2011-10-04 14:22) [1]

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


 
vlk32   (2011-10-04 14:24) [2]

Ви таки будете смеяться, но вот это работает правильно:

class function TArrayUtils<T>.ValidParams(const Arr:array of T; const A,B,C:Integer; const CMP:TCmpFunc<T>):Boolean;
 var L     : Integer;
     _CMP_ : TCmpFunc<T>;
 begin
  L     := Length(Arr);
  _CMP_ := cmp;
  Result :=
   (L>=2) and               // array must contain at least 2 elements
   (C>=0) and (C<=L) and    // count of used item must be in [0..L]
   (A<B) and                // A must be less than B
   (A>=0) and (B<=C-1) and  // work subarray must be in [0..C-1]
   Assigned(_CMP_);         // compare function must be assigned
 end;


Но когда я смотрб на этот код мне плакать хочется. Ну в чем же промблема?


 
Ega23 ©   (2011-10-04 14:42) [3]


> Ну в чем же промблема?


const?


 
vlk32   (2011-10-04 14:54) [4]

Убрал const результат для первого варианта функции все равно неправильный.

Да и по хорошему убирать оттуда const мне совесть не позволит. Параметр не изменяется внутри подпрограммы? Не изменяется. Так какого хера он не должен быть const?


 
Ega23 ©   (2011-10-04 15:01) [5]

CMP:TCmpFunc<T>

Что-то меня это дело смущает...


 
vlk32   (2011-10-04 15:07) [6]

Меня тоже, потому что проверок типа

if not Assigned(CMP) then Exit;

как грязи.


 
vlk32   (2011-10-04 15:08) [7]

TCmpFunc<T> = function(const Left,Right:T; const CMPData:LongWord=0):Integer;

не вижу крамолы. все законно.


 
Ega23 ©   (2011-10-04 15:14) [8]


> не вижу крамолы. все законно.


А где она потом объявляется?


 
oxffff ©   (2011-10-04 15:17) [9]

Замечено, что компилятор генерирует кривой код для generics в некоторых случаях.
Посмотри в отладчике изменяется ли регистр EAX(результат возвращается в нем) после строчки  Result :=.


 
vlk32   (2011-10-04 15:20) [10]

Так в том то и дело, что в данном случае параметр CMP, который передается в функцию = Nil, т.е. указатель на функцию сравнения не инициализирован. Это я четко вижу в окне локальных переменных во время отладки. Когда функция сравнения назначена (CMP<>Nil) то проблем то нет.

А объявляется она например вот так:


class procedure TCompareManager.AddNewComparer<T>(const FuncPtr:Pointer);
 var Info     : PTypeInfo;
     TypeName : AnsiString;
 begin
  if (FuncTable=Nil) or (FuncPtr=Nil) then Exit;
  //
  Info     := TypeInfo(T);
  TypeName := AnsiUpperCase(Info.Name);
  FuncTable.AddObject(TypeName,TObject(FuncPtr));
 end;

class procedure TCompareManager.InitTable;
 begin
  FuncTable := TStringList.Create;
  FuncTable.Duplicates    := dupError;
  FuncTable.CaseSensitive := False;
  FuncTable.Sorted        := True;
  //
  AddNewComparer<Boolean>      (@CMP_Boolean      );
  AddNewComparer<Integer>      (@CMP_Integer      );
  AddNewComparer<Byte>         (@CMP_Byte         );
  AddNewComparer<Real>         (@CMP_Real         );
  AddNewComparer<Pointer>      (@CMP_Pointer      );
  AddNewComparer<AnsiString>   (@CMP_AnsiString   );
  AddNewComparer<UnicodeString>(@CMP_UnicodeString);
 end;



 
oxffff ©   (2011-10-04 15:22) [11]


> oxffff ©   (04.10.11 15:17) [9]


Если причина в этом, то попробуй убрать галку Optimizations.
Если не поможет, придется переписать код.


 
oxffff ©   (2011-10-04 15:30) [12]


> Посмотри в отладчике изменяется ли регистр EAX(результат
> возвращается в нем) после строчки  Result :=.


Точнее конечно, посмотри откуда тянется результат в eax по выходу из метода.


 
vlk32   (2011-10-04 15:31) [13]

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

Жду когда же сделают нормальную компиляцию генериков. Задолдало каждый раз снимать внутренние ошибки компилятора. А отказываться от генериков уже нельзя. Тогда легче на C# перейти :(


 
oxffff ©   (2011-10-04 15:35) [14]

Посмотри в ASM отладчике в чем дело.


 
_Юрий   (2011-10-04 16:56) [15]


> TCmpFunc<T> = function(const Left,Right:T; const CMPData:
> LongWord=0):Integer;
>
> не вижу крамолы. все законно.


Думаю, ему не нравится необязательный параметр


 
oxffff ©   (2011-10-04 19:57) [16]

Версия  15.0.3953.35171
Полет нормальный. Код тоже.


 
Бездомный   (2011-10-06 13:42) [17]

А лучше ASM код скинуть сюда.



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

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

Наверх




Память: 0.51 MB
Время: 0.007 c
15-1368541324
Es
2013-05-14 18:22
2013.11.03
Падение приложения, crash без визуализации


15-1365950832
anikos
2013-04-14 18:47
2013.11.03
Взрыв при попадании


3-1293438440
avers_sm
2010-12-27 11:27
2013.11.03
Как передать TIBTransaction в качестве параметра процедуры.


8-1233235167
iworm
2009-01-29 16:19
2013.11.03
Line in


15-1368891373
Разведка
2013-05-18 19:36
2013.11.03
Помогите устроится программистом