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.
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:
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.