一个不起眼的问题,看能不能给圆满解答? ( 积分: 20 )

  • 主题发起人 主题发起人 BeCalm
  • 开始时间 开始时间
B

BeCalm

Unregistered / Unconfirmed
GUEST, unregistred user!
[?]请看代码:我认为这个函数永远返回False;原因是:Temp <> Name在i=0时永远成立,这样的话要这个函数有什么用处,希望高手解答???????
class function TObject.ClassNameIs(const Name: string): Boolean;
var
Temp: ShortString;
I: Byte;
begin
Result := False;
Temp := ClassName;
for I := 0 to Byte(Temp[0]) do
if Temp <> Name then Exit;
Result := True;
end;
 
看清楚整个再说!

class function TObject.ClassNameIs(const Name: string): Boolean;
{$IFDEF MSWINDOWS}
const
CSTR_EQUAL = 2;
LOCALE_SYSTEM_DEFAULT = 2048;
NORM_IGNORECASE = 1;
var
LClassName: string;
begin
LClassName := ClassName;
Result := CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, PChar(LClassName),
Length(LClassName), PChar(Name), Length(Name)) = CSTR_EQUAL;
end;
{$ELSE}
{$IFDEF PUREPASCAL}
var
Temp: ShortString;
I: Byte;
begin
Result := False;
Temp := ClassName;
for I := 0 to Byte(Temp[0]) do
if Temp <> Name then Exit;
Result := True;
end;
{$ELSE}
asm
PUSH EBX
XOR EBX,EBX
OR EDX,EDX
JE @@exit
MOV EAX,[EAX].vmtClassName
XOR ECX,ECX
MOV CL,[EAX]
CMP ECX,[EDX-4]
JNE @@exit
DEC EDX
@@loop:
MOV BH,[EAX+ECX]
XOR BH,[EDX+ECX]
AND BH,0DFH
JNE @@exit
DEC ECX
JNE @@loop
INC EBX
@@exit:
MOV AL,BL
POP EBX
end;
{$ENDIF}
{$ENDIF}
 
可是这点我不懂,这块代码在哪里?
$IFDEF MSWINDOWS}
const
CSTR_EQUAL = 2;
LOCALE_SYSTEM_DEFAULT = 2048;
NORM_IGNORECASE = 1;
var
LClassName: string;
begin
LClassName := ClassName;
Result := CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, PChar(LClassName),
Length(LClassName), PChar(Name), Length(Name)) = CSTR_EQUAL;
end;
{$ELSE}
也看不懂,当i=0时,那个Temp是指Temp的长度,而Name指name的第一个字符啊,还是没理解,请高手明示,呵呵[:(]
 
对于 ShortString 类型的字符串s s[0] 是字符串的长度
但 string 类型的字符串s s[0]是不可以访问的。
string类型是一个结构,在我们访问的地址前有12个字节,保存字符串占用的内容空间大小,引用计数,字符串长度。这个代码显然有问题。你可以看看asm的代码。

部分Delphi的内核源码同时提供两个版本,即“PUREPASCAL”和“BASM”版本。Delphi内核是以BASM版本编译的——PUREPASCAL版本的部分代码甚至在产品的正式版本中仍是有错误的。但通常而言,PUREPASCAL版本的代码是一个非常好的对照,也是学习BASM最佳的Sample。
 
maze78说的有道理,先加10分,呵呵,其它的,看还有没有其它的看法,你的看法就是说是delphi的代码错喽;我有点同意,呵呵
 
begin
Result := False;
if Temp[0] = 0 then Exit
// 加这一行就行了吧
Temp := ClassName;
for I := 0 to Byte(Temp[0]) do
if Temp <> Name then Exit;
Result := True;
end;
 
begin
Result := False;
if LengTh(Temp) = 0 then Exit
Temp := ClassName;
for I := 1 to LengTh(Temp) do
if Temp <> Name then Exit;
Result := True;
end;

不能直接访问Name[0]
 
还有没有什么高见,没有的话结帖了啊,同意delphi代码错误!!!
 
{$IFDEF PUREPASCAL}
var
Temp: ShortString;
I: Byte;
begin
Result := False;
Temp := ClassName;
for I := 0 to Byte(Temp[0]) do
if Temp <> Name then Exit;
Result := True;
end;
{$ELSE}
其实这段是没有错的,如果是在MSWindows运行,确实有问题, 但看上面{$IFDEF PUREPASCAL}
这不是一段运行在MSWindow下的代码, 在Purepascal里, 可以直接先对比string的长度的!
如果不相同, 有必要测下去吗, 当然return false;
 
多人接受答案了。
 
后退
顶部