6
votes

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:

True/False Table

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.

1
Have you looked at the generated assembler code?Dmitry Streblechenko
Not yet. Truthfully, even if it was different, I wouldn't have known what to fix, just that it's different.DelphiGuy

1 Answers

10
votes

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.