以下代码来自DDetours.pas。当它编译为32位时,没有发出警告。当它编译为64位时,它会发出此警告:(Delphi Berlin Update 2)
[dcc64 Hint] DDetours.pas(1019): H2077 Value assigned to 'Prf' never used
这是有问题的功能
function GetPrefixesCount(Prefixes: WORD): Byte;
var
Prf: WORD;
i: Byte;
begin
{ Get prefixes count used by the instruction. }
Result := 0;
if Prefixes = 0 then
Exit;
Prf := 0;
i := 0;
Prefixes := Prefixes and not Prf_VEX;
while Prf < $8000 do
begin
Prf := (1 shl i);
if (Prf and Prefixes = Prf) then
Inc(Result);
Inc(i);
end;
end;
在我看来,Prf首次与使用初始值的8000美元进行比较时确实很好。
答案 0 :(得分:2)
我怀疑 64位编译器内置少量智能,以便识别
repeat..until
循环一样。由于编译器仍然必须为初始化生成代码,但是知道在运行时不需要初始值来进入循环,它可以发出警告,初始值将不被使用。
如果不初始化变量,编译器在编译时不知道是否输入循环,因为行为未定义,因此编译器会发出有关未初始化变量的不同警告。 / p>
查看反汇编,您可以看到循环变为repeat..until
循环,并且优化删除了Prf := 0;
分配:
Project87.dpr.17: Result := 0;
00000000004261AA 4833D2 xor rdx,rdx
Project87.dpr.18: if Prefixes = 0 then
00000000004261AD 6685C0 test ax,ax
00000000004261B0 7460 jz GetPrefixesCount + $72
Project87.dpr.22: i := 0;
00000000004261B2 4D33C0 xor r8,r8
Project87.dpr.23: Prefixes := Prefixes and not Prf_VEX;
00000000004261B5 0FB7C0 movzx eax,ax
00000000004261B8 81E02DFBFFFF and eax,$fffffb2d
00000000004261BE 81F8FFFF0000 cmp eax,$0000ffff
00000000004261C4 7605 jbe GetPrefixesCount + $2B
00000000004261C6 E8050FFEFF call @BoundErr
Project87.dpr.26: Prf := (1 shl i);
00000000004261CB 41C7C101000000 mov r9d,$00000001
00000000004261D2 418BC8 mov ecx,r8d
00000000004261D5 41D3E1 shl r9d,r9b
00000000004261D8 4489C9 mov ecx,r9d
00000000004261DB 81F9FFFF0000 cmp ecx,$0000ffff
00000000004261E1 7605 jbe GetPrefixesCount + $48
00000000004261E3 E8E80EFEFF call @BoundErr
Project87.dpr.27: if (Prf and Prefixes = Prf) then
00000000004261E8 448BC9 mov r9d,ecx
00000000004261EB 664423C8 and r9w,ax
00000000004261EF 66443BC9 cmp r9w,cx
00000000004261F3 750A jnz GetPrefixesCount + $5F
Project87.dpr.28: Inc(Result);
00000000004261F5 80C201 add dl,$01
00000000004261F8 7305 jnb GetPrefixesCount + $5F
00000000004261FA E8F10EFEFF call @IntOver
Project87.dpr.29: Inc(i);
00000000004261FF 4180C001 add r8b,$01
0000000000426203 7305 jnb GetPrefixesCount + $6A
0000000000426205 E8E60EFEFF call @IntOver
Project87.dpr.24: while Prf < $8000 do
000000000042620A 6681F90080 cmp cx,$8000
000000000042620F 72BA jb GetPrefixesCount + $2B
答案 1 :(得分:1)
好吧,我想答案是dcc64在消息方面是一个错误的编译器。因为如果您注释掉违规行,那么#34;值从未使用过&#34;变得&#34;可能没有被初始化。&#34;相同的编译器。
[dcc64 Warning] DDetours.pas(1022): W1036 Variable 'Prf' might not have been initialized
答案 2 :(得分:1)
这是一个编译错误。这种性质有一些。相当令人沮丧。有时32位编译器会以不合理的方式抱怨,然后当您解决时,64位编译器反过来以一种不合理的方式抱怨您的解决方法。
我不认为Embarcadero习惯性地使用提示和警告进行编译,因为他们的库代码充满了提示和警告。
无论如何,在这种情况下,编译器会看到对变量的两次写入,但由于某种原因无法识别变量的介入读取。
你可以做的事情不多。您可以提交错误报告。我希望您不想更改代码,因为它是第三方代码。如果你不改变它,那么你将不得不忍受伪造的暗示。
通知图书馆的作者可能会允许他们解决问题。也许通过抑制该功能的提示。