Форум: "Основная";
Текущий архив: 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