-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove usage of old safe math and unused intsafe.h include #8479
Remove usage of old safe math and unused intsafe.h include #8479
Conversation
#pragma prefast(push) | ||
#pragma prefast(disable : 26071, "Range violation in Intsafe. Not ours.") | ||
#define ENABLE_INTSAFE_SIGNED_FUNCTIONS // Only unsigned intsafe math/casts available without this def | ||
#include <intsafe.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I remember that interactivity should not be changed in this repo. But I removed the <intsafe.h>
in ../../host/precomp.h
so I had to add it back here to make the project compile.
New misspellings found, please review:
To accept these changes, run the following commands
✏️ Contributor please read thisBy default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
If the listed items are:
See the 🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The :check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉
|
From the discussion we had in issue #4013, I got the impression we'd be getting cleaner, more readable code from the new safe math library, so I've got to say these changes are a little disappointing. What exactly are the benefits we're getting here? And it looks like the new lib is introducing some behavioural changes too - the overflow tests look slightly different to me, and the error codes returned are different. Is this intentional? And the one behavioural change I was expecting was greater use of clamping instead of failing on overflow, but that doesn't seem to have happened. If all we're doing is replacing one unreadable library with a slightly more unreadable library (and risking introducing new bugs in the process) is this really worth the effort? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all seems sensible to me, thanks for cleaning this up!
@msftbot make sure @miniksa signs off on this one |
Hello @zadjii-msft! Because you've given me some instructions on how to help merge this pull request, I'll be modifying my merge approach. Here's how I understand your requirements for merging this pull request:
If this doesn't seem right to you, you can tell me to cancel these instructions and use the auto-merge policy that has been configured for this repository. Try telling me "forget everything I just told you". |
ptrdiff_t rowOffset = 0; | ||
RETURN_IF_FAILED(PtrdiffTSub(target.Y, requestRectangle.Top(), &rowOffset)); | ||
RETURN_IF_FAILED(PtrdiffTMult(rowOffset, requestRectangle.Width(), &rowOffset)); | ||
RETURN_HR_IF(E_ABORT, !base::CheckSub<LONGLONG>(target.Y, requestRectangle.Top()).AssignIfValid(&rowOffset)); | ||
RETURN_HR_IF(E_ABORT, !base::CheckMul<LONGLONG>(rowOffset, requestRectangle.Width()).AssignIfValid(&rowOffset)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't all of these PtrdiffT calculations be using ptrdiff_t
for the type? I don't think it's the same as LONGLONG
in a 32bit build.
THROW_HR_IF(E_ABORT, !base::CheckAdd(newLeft, delta.X).AssignIfValid(&newLeft)); | ||
THROW_HR_IF(E_ABORT, !base::CheckAdd(newRight, delta.X).AssignIfValid(&newRight)); | ||
THROW_HR_IF(E_ABORT, !base::CheckAdd(newTop, delta.Y).AssignIfValid(&newTop)); | ||
THROW_HR_IF(E_ABORT, !base::CheckAdd(newBottom, delta.Y).AssignIfValid(&newBottom)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't these E_ABORT
errors be INTSAFE_E_ARITHMETIC_OVERFLOW
if we want to remain compatible with the original code? It's probably not a big deal, but it's theoretically possible someone could be checking for specific error returns in some situation, especially if the return code is exposed in a public API somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although I suppose if we want to get rid of the intsafe.h dependency then I guess that's not an option, unless you want to redefine the constant, or hardcode the error number. I don't know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum. You're right that it probably should maintain the error code in case anyone's checking specifically for it.... but I also highly doubt that anyone is given that I probably introduced it in the last few years and most things I've ever found are only checking overall success/failure from any of our API returns (if they even check at all and don't just steamroll anyway).
If we're worried about it, I don't mind redefining that constant without the header if the goal is to remove the header. But also, I don't super mind if it just becomes a different error code either...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah OK. The more I think about it, the more I think it's probably not a big deal, especially if this code was only a fairly recent addition.
@@ -43,8 +43,8 @@ try | |||
RETURN_BOOL_IF_FALSE(SUCCEEDED(SizeTToShort(column, &x)) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@j4james had mentioned in the linked issue that we should probably replace these type conversions too to use the saturating math at the same time. If these aren't coming in from intsafe.h
, where are they coming from? We should probably either do these in a batch with this PR or ensure we do a follow up to get them too for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dang these aren't coming directly from intsafe.h
but by including some win32 headers which indirectly include intsafe.h
, these macros are still available. For example wil has it in https://github.com/microsoft/wil/blob/master/include/wil/safecast.h
This makes me feel that this PR isn't really doing much..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm. Darn ok.
I feel about the same. I can’t say I fully endorse this PR in terms of readability. But I still think that chromium safe math is better in terms of extensibility and modern code style. Well, “normal” cpp code does not use HRESULT as its return value and HRESULT is exactly what THROW wants. Maybe we just can not have the best of the both worlds, huh. I bet @miniksa can think of better reasons than me. |
Well what I was hoping would happen is we'd either be using clamped math, in which case there wouldn't be any error return value, or we'd be using a form of checked math that threw an exception, in which case the error handling could be dealt with neatly in one place (instead of every single expression having an error check on it). And once we're not doing error checking on every operation, we're in a much better position to be using regular math operators with safe math types, which I think should be much more readable than all these |
That is true. The I know I'd find it mentally easier to do two more straight forward migrations than to have one more complicated one. But simultaneously, I can't see the core team getting to this any time soon... so I'm willing to concede whichever one is easier for the ones who are ambitious enough to do this work. If that's going straight to throwing-style calls with the bare operators on the safe math objects... (and of course catching the exception and routing it back to an HRESULT/NTSTATUS for the API call when necessary) that's fine with me.
This has just evolved from old Windows-style C code. Thus the return code focus and no real exceptions until recent-ish additions or modifications. That's why everything is so mixed. But we're ready and willing to adopt exceptions now as long as the console API functionality is maintained to the perspective of clients (within reason). Thus if you want to close this issue/PR as "dumb/pointless/outdated" and transform the work into something that is overall prettier and more faithfully represents C++ and utilizes the Chromium math libraries to their potential... I'm cool with it. |
After some consideration I'm still not convinced that this is good enough. I'll close it for now. Thanks everyone for the explanation and comments. |
Summary of the Pull Request
References
#4144 introduced the chromium safe math library.
PR Checklist
Detailed Description of the Pull Request / Additional comments
Validation Steps Performed