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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.003 c
11-1248443105
DevilDevil
2009-07-24 17:45
2013.11.03
Горизонтальный ScrollBar


2-1357887539
vrem
2013-01-11 10:58
2013.11.03
Память естся, подскажите как исправить для такого вызова:


15-1368647469
Rouse_
2013-05-15 23:51
2013.11.03
ВУЗ для IT специалиста: взгляд изнутри


3-1293005098
Андрей Пл
2010-12-22 11:04
2013.11.03
Сравнение таблиц по срок.полям (лишние внутренние пробелы)


15-1368995402
Юрий
2013-05-20 00:30
2013.11.03
С днем рождения ! 20 мая 2013 понедельник





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