Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.152 Beiträge
 
Delphi 12 Athens
 
#22

AW: Verständnisfrage: IF (Bedingung1 ODER Bedingung1)

  Alt 19. Okt 2016, 10:24
Ich hab grade im XE einen eigenartigen Fehler gefunden.
Da sucht man sich echt dumm und dusselig danach, wenn das ab und an in einen OnPopup auftritt,
denn die erste Codezeile läuft erfolgreich durch und die Zweite knallt, mit einer wunderschönen Zugriffsverletzung.

Obj.Count=0 und daher löst Obj.Prop[0] eine Exception aus.
Delphi-Quellcode:
xxx.Enabled := (Obj.Count = 1) and (Obj.Prop[0].GetVariant('ein String') = 'xxx');
xxx.Enabled := (Obj.Count = 1) and not Obj.Prop[0].GetVariant('ein Boolean');
Hatte erst geschaut, ob {$BoolEval} ausversehn aktiv ist, aber nee.
Es knallt einfach, wenn ein implizier Cast auftritt, weil trots {$BoolEval off} der Getter ausgeführt wird
und bei einem explizitem VarAsBool oder Boolean-Cast drumrum, passiert das nicht.
Delphi-Quellcode:
xxx.Enabled := (Obj.Count = 1) and not Obj.Prop[0].GetVariant('ein Boolean'); // knallt
xxx.Enabled := (Obj.Count = 1) and not Boolean(Obj.Prop[0].GetVariant('ein Boolean')); // knallt nicht
xxx.Enabled := (Obj.Count = 1) and not VarAsBool(Obj.Prop[0].GetVariant('ein Boolean')); // knallt och ni
Nach Analyse des Codes, seh ich, dass der Compiler nicht den zweiten Paramter in einen Boolean castet und dann einfach nur ein AND macht,
sondern es wird der erste Parameter in einen Variant gecastet und dann das Ganze in VarAnd(variant, variant): boolean reingequetscht.

Tolle Leisung, vom Compiler. :thumbsup:

xxx.Enabled := (Obj.Count = 1) and not VarToBool(Obj.Prop[0].GetVariant('ein Boolean')); // das IMHO Logische
xxx.Enabled := VarAnd(VarFromBool(Obj.Count = 1), VarNot(Obj.Prop[0].GetVariant('ein Boolean'))); // die Idee des Compiler

Code:
// VarAsBool
mov eax,[ebp-$04]
mov eax,[eax+$00000430]
call $0ea6d894  // GetCount
dec eax
jnz $0ea7bc20
xor edx,edx
mov eax,[ebp-$04]
mov eax,[eax+$00000430]
call $0ea6d89c // GetProp
lea ecx,[ebp-$38]
mov edx,$0ea7c150
call $0ea6d98c // GetVariant
lea eax,[ebp-$38]
call $0ea53264  // VarAsBool
test al,al
jz $0ea7bc24
xor edx,edx
jmp $0ea7bc26
mov dl,$01
mov eax,[ebp-$04]
mov eax,[eax+$000004e4]
call $0ea53024  // SetEnabled

// Boolean
mov eax,[ebp-$04]
mov eax,[eax+$00000430]
call $0ea6d894  // GetCount
dec eax
jnz $0ea7bc89
xor edx,edx
mov eax,[ebp-$04]
mov eax,[eax+$00000430]
call $0ea6d89c // GetProp
lea ecx,[ebp-$48]
mov edx,$0ea7c150
call $0ea6d98c // GetVariant
lea eax,[ebp-$48]
call $0ea51668  // VarToBool
test al,al
jz $0ea7bc8d
xor edx,edx
jmp $0ea7bc8f
mov dl,$01
mov eax,[ebp-$04]
mov eax,[eax+$000004e4]
call $0ea53024  // SetEnabled

// implizit
mov eax,[ebp-$04]
mov eax,[eax+$00000430]
call $0ea6d894  // GetCount
dec eax
setz dl
lea eax,[ebp-$58]
call $0ea51680  // VarFromBool
lea eax,[ebp-$58]
push eax
xor edx,edx
mov eax,[ebp-$04]
mov eax,[eax+$00000430]
call $0ea6d89c // GetProp <- hier knallt's dann
lea ecx,[ebp-$68]
mov edx,$0ea7c150
call $0ea6d98c // GetVariant
lea eax,[ebp-$68]
call $0ea516a8  // VarNot
lea edx,[ebp-$68]
pop eax
call $0ea516f0  // VarAnd
lea eax,[ebp-$58]
call $0ea51668  // VarToBool
mov edx,eax
mov eax,[ebp-$04]
mov eax,[eax+$000004e4]
call $0ea53024  // SetEnabled
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat