Delphi Inline Changes Answer to Bit Reading
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.
delphi bit
add a comment |
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.
delphi bit
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
add a comment |
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.
delphi bit
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.
delphi bit
delphi bit
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
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.
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 literal1
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
|
show 1 more comment
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 literal1
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
|
show 1 more comment
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.
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 literal1
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
|
show 1 more comment
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.
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.
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 literal1
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
|
show 1 more comment
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 literal1
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
|
show 1 more comment
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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