Mercury Bugs - mercury
View Issue Details
0000503mercuryFeature Requestpublic2020-04-28 23:512020-04-29 17:25
Assigned To 
PrioritynormalSeverityminorReproducibilityhave not tried
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0000503: unsigned shift amounts
DescriptionAt the moment, the shift amount is always a signed int, even when the
value being shifted has type uint. It should be possible to make the shift amount
an unsigned int. This would have the advantage that of the two checks that
checked shifts have to do, checking for negative shift amounts and checking for
shift amounts bigger than the word size, an unsigned shift amount would need
only the latter.

The key question is the syntax. Unlike e.g. C++, we cannot overload <<, >>, and
their unchecked equivalents; we would need new function names. I can see
using either <<< and >>>, or <<u and >>u as the names of the unsigned
versions of << and >>. And maybe unchecked_{left,right}_shift_by_uint
or unchecked_{left,right}_ushift for their unchecked versions.

Any ideas for better names, or opinions on these names?
TagsNo tags attached.
Attached Files

2020-04-29 16:26   
The two checks are supposed to be performed using a single unsigned comparison on the shift amount, so is there anything to gain?

I don't think the new operators would be used enough to justify them. Also, Java has >>> meaning logical right shift (I had to look that up) -- it would be best not to introduce operators that conflict with operators in well known languages.
2020-04-29 16:39   
The gain I am after is not efficiency. The gain is being able to write code
such as "1u <<u NumBits" instead of "1u << uint.cast_to_int(NumBits)".
I am working on a version of du_type_layout.m that would work at
"create .int file" time instead of code generation time, and that code
is full of things that cannot be negative: number of arguments in a functor,
word lengths, bitfield sizes, shift amount etc. It is a pain having to choose

(a) using ints, and losing the >= 0 invariant, and
(b) using uints, and having to pepper calls to most library functions
with casts, because those functions take only signed ints, to the extent
that the casts obscure the actual logic of the code.
2020-04-29 16:40   
On the topic of avoiding >>>, I agree; if we don't have to create
such conflicts of notation, we shouldn't.
2020-04-29 17:03   
You could define an overload in a compiler module to improve clarity:

:- func uint << uint = uint.

X << Y = uint.(X << cast_to_int(Y)).

That is not to say we should not add named functions taking unsigned shift amounts to the standard library.
2020-04-29 17:25   
Java only has >>> for logical right shifts because it doesn't support unsigned types but does provide (some) unsigned operations on its signed types. AFAIK, it is the only well known language that has that.

I'd be fine with unchecked_{left, right}_ushift for the unchecked versions. I'm not really a fan of things like >>u and <<u, but I can probably live with them. (I guess just having the functions left_ushift and right_ushift is too ungainly?)

Issue History
2020-04-28 23:51zsNew Issue
2020-04-29 16:26wangpNote Added: 0001085
2020-04-29 16:39zsNote Added: 0001086
2020-04-29 16:40zsNote Added: 0001087
2020-04-29 17:03wangpNote Added: 0001088
2020-04-29 17:25juliensfNote Added: 0001089