delphi – 测试字符串长度比与空字符串相比产生更多代码?
在Delphi中,字符串<> ”似乎生成的代码少于Length(string)> 0.
比较在TMyClass.UpdateString(const strMyString:String)中定义的空字符串: MyClassU.pas.31: begin 005CE6A0 55 push ebp 005CE6A1 8BEC mov ebp,esp 005CE6A3 83C4F8 add esp,-$08 005CE6A6 8955F8 mov [ebp-$08],edx 005CE6A9 8945FC mov [ebp-$04],eax MyClassU.pas.32: if (strMyString <> '') then 005CE6AC 837DF800 cmp dword ptr [ebp-$08],$00 005CE6B0 740E jz $005ce6c0 据我了解,这是将动态分配的字符串([ebp- $08])的地址与零进行比较.有道理,因为空字符串point to 比较长度,在TMyClass.UpdateString2(const strMyString:String)中定义: MyClassU.pas.25: begin 005CE664 55 push ebp 005CE665 8BEC mov ebp,esp 005CE667 83C4F4 add esp,-$0c 005CE66A 8955F8 mov [ebp-$08],edx 005CE66D 8945FC mov [ebp-$04],eax 005CE670 8B45F8 mov eax,[ebp-$08] MyClassU.pas.26: if (Length(strMyString) > 0) then 005CE673 8945F4 mov [ebp-$0c],eax 005CE676 837DF400 cmp dword ptr [ebp-$0c],$00 005CE67A 740B jz $005ce687 005CE67C 8B45F4 mov eax,[ebp-$0c] 005CE67F 83E804 sub eax,$04 005CE682 8B00 mov eax,[eax] 005CE684 8945F4 mov [ebp-$0c],eax 005CE687 837DF400 cmp dword ptr [ebp-$0c],$00 005CE68B 7E0E jle $005ce69b 什么?它应该只是cmp dword ptr [ebp- $04],$00,字符串长度为is stored at offset -$04 within the string? 我的猜测是因为优化已关闭且编译器没有优化Lenght(归结为PInteger(PByte(S) – 4)^),但我不明白为什么有两个比较.事实上,即使启用了优化,两种比较都会出现: MyClassU.pas.27: if (Length(strMyString) > 0) then 005CE6B1 8BC6 mov eax,esi 005CE6B3 85C0 test eax,eax 005CE6B5 7405 jz $005ce6bc 005CE6B7 83E804 sub eax,$04 005CE6BA 8B00 mov eax,[eax] 005CE6BC 85C0 test eax,eax 005CE6BE 7E0A jle $005ce6ca VS MyClassU.pas.33: if (strMyString <> '') then 005CE6D9 85F6 test esi,esi 005CE6DB 740A jz $005ce6e7 解决方法
第二个代码块做了更多的工作,并且毫不奇怪,需要更多的代码.
在第一个代码块中,您只需与空字符串进行比较.编译器知道这相当于将指针与nil进行比较并生成该代码. 第二个代码块首先获得字符串的长度.这涉及检查指针是否为零.如果是,则长度为零.否则,从字符串元数据记录中读取长度. 编译器根本不知道每次指针不是nil时,长度必须为正,因此无法优化. 至于为什么Length不直接从字符串记录中读取,现在应该是显而易见的.空字符串实现为nil指针,因此没有字符串记录.为了找到处理两种不同情况所需的长度: >字符串为空,长度为0.>字符串不为空,从字符串记录中读取长度. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |