Defined behavior for shifting with oversized or negative values. #739
SRNissen
started this conversation in
Suggestions
Replies: 1 comment
-
NB: I have only checked for shift right. I would be terribly embarrassed if it turns out this doesn't work for left shifting but my wrist is acting up so I'll let it rest. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
This is an outgrowth of a brief discussion I had on /r/cpp_questions
Background:
With the standardization of
[[assume()]]
in C++23, we have reached a point where regular C++ could chose to accept the performance sacrifice of clamping shift values to fully definine the behavior of outsized shifts, letting you opt back in to the older (faster, unclamped) behavior by stating that youassume
your value is valid for shifting without clamping.(see godbolt, or the end of this post, for an example where shifting is fully defined in the default case, and where that same shifting function emits assembly identical to an old style UB shift in the face of assumptions)
Suggestion for cppfront
In the spirit of "Safety first unless you opt in to faster unsafe behavior," I would like to suggest that shifting left and right, by any value, should be fully defined behavior unless you opt in to the faster UB implementation.
Alternatively, if changing the semantics of operators isn't in scope for this project,
>>
and<<
should emit warnings on every use and a "safe shift left" and "safe shift right" function should be available.I have no opinion on whether a shift with a negative value should be skipped, or whether it should produce a shift in the opposite direction or, dark horse candidate, if there should only be one shift operator and the sign of the shift value determines shift direction.
Example code
Godbolt
When compiled, the safe shift emits more instructions than the two unsafe shifts, but does not do any extremely silly things like branch on the shift value.
Importantly: The unsafe shift with explicit assumptions emits the exact same assembly as the old-style unsafe shift with implicit assumptions, despite using the same shift function as the safe shift.
Beta Was this translation helpful? Give feedback.
All reactions