Delphi Inline Changes Answer to Bit Reading










6














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.










share|improve this question





















  • Have you looked at the generated assembler code?
    – Dmitry Streblechenko
    Nov 12 '18 at 19:37










  • Not yet. Truthfully, even if it was different, I wouldn't have known what to fix, just that it's different.
    – DelphiGuy
    Nov 12 '18 at 22:32















6














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.










share|improve this question





















  • Have you looked at the generated assembler code?
    – Dmitry Streblechenko
    Nov 12 '18 at 19:37










  • Not yet. Truthfully, even if it was different, I wouldn't have known what to fix, just that it's different.
    – DelphiGuy
    Nov 12 '18 at 22:32













6












6








6







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.










share|improve this question













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.







delphi bit






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 12 '18 at 19:16









DelphiGuy

917




917











  • Have you looked at the generated assembler code?
    – Dmitry Streblechenko
    Nov 12 '18 at 19:37










  • Not yet. Truthfully, even if it was different, I wouldn't have known what to fix, just that it's different.
    – DelphiGuy
    Nov 12 '18 at 22:32
















  • Have you looked at the generated assembler code?
    – Dmitry Streblechenko
    Nov 12 '18 at 19:37










  • Not yet. Truthfully, even if it was different, I wouldn't have known what to fix, just that it's different.
    – DelphiGuy
    Nov 12 '18 at 22:32















Have you looked at the generated assembler code?
– Dmitry Streblechenko
Nov 12 '18 at 19:37




Have you looked at the generated assembler code?
– Dmitry Streblechenko
Nov 12 '18 at 19:37












Not yet. Truthfully, even if it was different, I wouldn't have known what to fix, just that it's different.
– DelphiGuy
Nov 12 '18 at 22:32




Not yet. Truthfully, even if it was different, I wouldn't have known what to fix, just that it's different.
– DelphiGuy
Nov 12 '18 at 22:32












1 Answer
1






active

oldest

votes


















10














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.






share|improve this answer






















  • Thanks for that. I'll give that a try. I still don't quite get why it's a 32-bit context when ABitIdx is a UInt64? Having the answer switch when inlining or switching to a release version is pretty touchy though. Definitely requires extra care and feeding. :-)
    – DelphiGuy
    Nov 12 '18 at 22:10










  • ABitInd must be less than 64 so no point at all in wasting a 64 bit type on it. What counts is the type of the lhs of the expression, the literal 1 in your code
    – David Heffernan
    Nov 12 '18 at 22:34










  • Also, curious: Why does the Button2Click work if it's passed as a 32-bit integer instead of a constant?
    – DelphiGuy
    Nov 12 '18 at 22:35










  • I don't really know. Chance? I think it's ill defined. Very possibly a bug. But one that disappears when you fix the bug in your code
    – David Heffernan
    Nov 12 '18 at 22:38










  • Agreed that a 64-bit type is a waste. That was the attempt to get it to a 64-bit context. >>What counts is the type of the lhs of the expression, the literal 1 in your code. Could you enlighten me on "lhs"?
    – DelphiGuy
    Nov 12 '18 at 22:50










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268687%2fdelphi-inline-changes-answer-to-bit-reading%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









10














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.






share|improve this answer






















  • Thanks for that. I'll give that a try. I still don't quite get why it's a 32-bit context when ABitIdx is a UInt64? Having the answer switch when inlining or switching to a release version is pretty touchy though. Definitely requires extra care and feeding. :-)
    – DelphiGuy
    Nov 12 '18 at 22:10










  • ABitInd must be less than 64 so no point at all in wasting a 64 bit type on it. What counts is the type of the lhs of the expression, the literal 1 in your code
    – David Heffernan
    Nov 12 '18 at 22:34










  • Also, curious: Why does the Button2Click work if it's passed as a 32-bit integer instead of a constant?
    – DelphiGuy
    Nov 12 '18 at 22:35










  • I don't really know. Chance? I think it's ill defined. Very possibly a bug. But one that disappears when you fix the bug in your code
    – David Heffernan
    Nov 12 '18 at 22:38










  • Agreed that a 64-bit type is a waste. That was the attempt to get it to a 64-bit context. >>What counts is the type of the lhs of the expression, the literal 1 in your code. Could you enlighten me on "lhs"?
    – DelphiGuy
    Nov 12 '18 at 22:50















10














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.






share|improve this answer






















  • Thanks for that. I'll give that a try. I still don't quite get why it's a 32-bit context when ABitIdx is a UInt64? Having the answer switch when inlining or switching to a release version is pretty touchy though. Definitely requires extra care and feeding. :-)
    – DelphiGuy
    Nov 12 '18 at 22:10










  • ABitInd must be less than 64 so no point at all in wasting a 64 bit type on it. What counts is the type of the lhs of the expression, the literal 1 in your code
    – David Heffernan
    Nov 12 '18 at 22:34










  • Also, curious: Why does the Button2Click work if it's passed as a 32-bit integer instead of a constant?
    – DelphiGuy
    Nov 12 '18 at 22:35










  • I don't really know. Chance? I think it's ill defined. Very possibly a bug. But one that disappears when you fix the bug in your code
    – David Heffernan
    Nov 12 '18 at 22:38










  • Agreed that a 64-bit type is a waste. That was the attempt to get it to a 64-bit context. >>What counts is the type of the lhs of the expression, the literal 1 in your code. Could you enlighten me on "lhs"?
    – DelphiGuy
    Nov 12 '18 at 22:50













10












10








10






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.






share|improve this answer














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.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 12 '18 at 20:28

























answered Nov 12 '18 at 19:52









David Heffernan

515k348131205




515k348131205











  • Thanks for that. I'll give that a try. I still don't quite get why it's a 32-bit context when ABitIdx is a UInt64? Having the answer switch when inlining or switching to a release version is pretty touchy though. Definitely requires extra care and feeding. :-)
    – DelphiGuy
    Nov 12 '18 at 22:10










  • ABitInd must be less than 64 so no point at all in wasting a 64 bit type on it. What counts is the type of the lhs of the expression, the literal 1 in your code
    – David Heffernan
    Nov 12 '18 at 22:34










  • Also, curious: Why does the Button2Click work if it's passed as a 32-bit integer instead of a constant?
    – DelphiGuy
    Nov 12 '18 at 22:35










  • I don't really know. Chance? I think it's ill defined. Very possibly a bug. But one that disappears when you fix the bug in your code
    – David Heffernan
    Nov 12 '18 at 22:38










  • Agreed that a 64-bit type is a waste. That was the attempt to get it to a 64-bit context. >>What counts is the type of the lhs of the expression, the literal 1 in your code. Could you enlighten me on "lhs"?
    – DelphiGuy
    Nov 12 '18 at 22:50
















  • Thanks for that. I'll give that a try. I still don't quite get why it's a 32-bit context when ABitIdx is a UInt64? Having the answer switch when inlining or switching to a release version is pretty touchy though. Definitely requires extra care and feeding. :-)
    – DelphiGuy
    Nov 12 '18 at 22:10










  • ABitInd must be less than 64 so no point at all in wasting a 64 bit type on it. What counts is the type of the lhs of the expression, the literal 1 in your code
    – David Heffernan
    Nov 12 '18 at 22:34










  • Also, curious: Why does the Button2Click work if it's passed as a 32-bit integer instead of a constant?
    – DelphiGuy
    Nov 12 '18 at 22:35










  • I don't really know. Chance? I think it's ill defined. Very possibly a bug. But one that disappears when you fix the bug in your code
    – David Heffernan
    Nov 12 '18 at 22:38










  • Agreed that a 64-bit type is a waste. That was the attempt to get it to a 64-bit context. >>What counts is the type of the lhs of the expression, the literal 1 in your code. Could you enlighten me on "lhs"?
    – DelphiGuy
    Nov 12 '18 at 22:50















Thanks for that. I'll give that a try. I still don't quite get why it's a 32-bit context when ABitIdx is a UInt64? Having the answer switch when inlining or switching to a release version is pretty touchy though. Definitely requires extra care and feeding. :-)
– DelphiGuy
Nov 12 '18 at 22:10




Thanks for that. I'll give that a try. I still don't quite get why it's a 32-bit context when ABitIdx is a UInt64? Having the answer switch when inlining or switching to a release version is pretty touchy though. Definitely requires extra care and feeding. :-)
– DelphiGuy
Nov 12 '18 at 22:10












ABitInd must be less than 64 so no point at all in wasting a 64 bit type on it. What counts is the type of the lhs of the expression, the literal 1 in your code
– David Heffernan
Nov 12 '18 at 22:34




ABitInd must be less than 64 so no point at all in wasting a 64 bit type on it. What counts is the type of the lhs of the expression, the literal 1 in your code
– David Heffernan
Nov 12 '18 at 22:34












Also, curious: Why does the Button2Click work if it's passed as a 32-bit integer instead of a constant?
– DelphiGuy
Nov 12 '18 at 22:35




Also, curious: Why does the Button2Click work if it's passed as a 32-bit integer instead of a constant?
– DelphiGuy
Nov 12 '18 at 22:35












I don't really know. Chance? I think it's ill defined. Very possibly a bug. But one that disappears when you fix the bug in your code
– David Heffernan
Nov 12 '18 at 22:38




I don't really know. Chance? I think it's ill defined. Very possibly a bug. But one that disappears when you fix the bug in your code
– David Heffernan
Nov 12 '18 at 22:38












Agreed that a 64-bit type is a waste. That was the attempt to get it to a 64-bit context. >>What counts is the type of the lhs of the expression, the literal 1 in your code. Could you enlighten me on "lhs"?
– DelphiGuy
Nov 12 '18 at 22:50




Agreed that a 64-bit type is a waste. That was the attempt to get it to a 64-bit context. >>What counts is the type of the lhs of the expression, the literal 1 in your code. Could you enlighten me on "lhs"?
– DelphiGuy
Nov 12 '18 at 22:50

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268687%2fdelphi-inline-changes-answer-to-bit-reading%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Barbados

How to read a connectionString WITH PROVIDER in .NET Core?

Node.js Script on GitHub Pages or Amazon S3