I'm using Delphi Berlin with default compiler options. I'm doing some bit routines and have a case that where inline changes the answer.
My code:
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;
For Button1Click, the answer changes from False (which looks correct) to True when inline is added. My table below is:
Button2Click, which just replaces the constant with a variable, always yields False.
I was running a large amount of bit checking and setting and came across this anomaly. That why the random hex number is here.
I also have a case with the same hex number and bit 31 in a larger project that yields different results based upon Debug or Release. Unable to simplify that yet to a reasonable example.
The code looks correct. I found a similar function for 32-bits here:
Bit Manipulation Using Delphi
So my question is why would the inline word change the answer?
Thanks for any help.
Your code is wrong in because the bitwise shift is performed in a 32 bit context. You must write it like this
Result := ((UInt64(1) shl ABitIdx) and AQWord)<>0;
where the cast forces 64 bit arithmetic.
So whilst it seems wrong that the inlined version of the code behaves differently from the non-inlined version, I suspect that the real issue is that your code's behaviour is ill-defined. Once you fix the code, as shown above, you will find that the inlined and non-inlined versions behave the same, and give the correct answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With