我正在使用带有默认编译器选项的 Delphi Berlin。我正在做一些位例程,并且有一个情况,内联改变了答案。
我的代码:
function BitGetFromQWord( const AQWord: UInt64; ABitIdx: UInt64 ): Boolean; //inline;
begin
Assert( ABitIdx<64 );
Result := ((1 shl ABitIdx) and AQWord)<>0;
end;
procedure TForm22.Button1Click(Sender: TObject);
begin
ShowMessage( BoolToStr( BitGetFromQWord( $CBBE02D50FD8262F, 31 ), True ) );
end;
procedure TForm22.Button2Click(Sender: TObject);
var
x: Integer;
begin
x := 31;
ShowMessage( BoolToStr( BitGetFromQWord( $CBBE02D50FD8262F, x ), True ) );
end;
对于 Button1Click,添加内联后,答案从 False(看起来正确)更改为 True。我的下表是:
Button2Click 只是用变量替换常量,总是产生 False。
我运行了大量的位检查和设置,并遇到了这个异常。这就是为什么随机十六进制数字在这里的原因。
我在一个较大的项目中还有一个具有相同十六进制数字和位 31 的案例,它根据调试或发布产生不同的结果。尚无法将其简化为合理的示例。
代码看起来正确。我在这里找到了 32 位的类似函数:
所以我的问题是为什么内联词会改变答案?
感谢您的帮助。
最佳答案
您的代码是错误的,因为按位移位是在 32 位上下文中执行的。你必须这样写
Result := ((UInt64(1) shl ABitIdx) and AQWord)<>0;
其中强制转换为 64 位算术。
因此,虽然代码的内联版本与非内联版本的行为不同似乎是错误的,但我怀疑真正的问题是代码的行为定义不明确。一旦你修复了代码,如上所示,你会发现内联和非内联版本的行为相同,并给出正确的答案。
关于Delphi 内联更改了位读取的答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53268687/