<div dir="ltr">We'd still need to define the behavior of signed shifting when encoding<T>==binary_system::twos_complement, for it to help this use case.<div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 17, 2014 at 11:59 AM, Gabriel Dos Reis <span dir="ltr"><<a href="mailto:gdr@microsoft.com" target="_blank" class="cremed">gdr@microsoft.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Or require implementations to tell you programmatically what they are using as binary representation:<br>
<br>
enum class binary_system {<br>
other,<br>
sign_magnitude,<br>
ones_complement,<br>
twos_complement<br>
};<br>
<br>
template<BuiltinIntegralType T><br>
constexpr binary_system encoding = /* implementation defined */<br>
<br>
-- Gaby<br>
<span class="im HOEnZb"><br>
| -----Original Message-----<br>
| From: <a href="mailto:ub-bounces@open-std.org" class="cremed">ub-bounces@open-std.org</a> [mailto:<a href="mailto:ub-bounces@open-std.org" class="cremed">ub-bounces@open-std.org</a>] On<br>
| Behalf Of Jeffrey Yasskin<br>
| Sent: Monday, November 17, 2014 11:11 AM<br>
| To: WG21 UB study group<br>
| Subject: Re: [ub] Signed shifting<br>
|<br>
</span><div class="HOEnZb"><div class="h5">| * The last thread on two's-complement representation managed to find<br>
| one modern Unisys system that uses one's-complement, and the thread<br>
| reported that this one supports Java, so it has to have a way to<br>
| execute two's-complement shifts. We shouldn't be building a standard<br>
| for imaginary systems.<br>
|<br>
| * Even if 'int' needs to support non-two's-complement, the referenced<br>
| code<br>
| (<a href="https://github.com/teor2345/tor/blob/ced74e0144e967f838416e6af92cba6" target="_blank" class="cremed">https://github.com/teor2345/tor/blob/ced74e0144e967f838416e6af92cba6</a><br>
| 5c007d89b/src/ext/curve25519_donna/curve25519-donna.c#L56)<br>
| uses int64_t, which <C99 7.18.1.1 Exact-width integer types> says is<br>
| already two's complement. C++14 defers to C99 for this. We could<br>
| define shifts on two's complement types that would stay<br>
| implementation-defined on anything else.<br>
|<br>
| * Programmers are used to writing "X << N" to mean "X * 2^N". Without<br>
| a good reason, we shouldn't make them use worse syntax for this, even<br>
| for signed numbers. "Applying [bit-shifts] to signed numbers is a bug"<br>
| is just incorrect given compilers' and hardware's actual behavior.<br>
| (Appealing to the fact that it's undefined behavior in the current<br>
| standard is just begging the question.)<br>
|<br>
| * If we wanted to provide a library function to represent shifting,<br>
| I'm having trouble coming up with a good name for it. A free library<br>
| function operating on integers is terrible: times_two_to_the(X, N)? A<br>
| member function for the constant-time class that competes with "<< N"<br>
| is also hard to produce: X.times_two_to_the(N)? X.times_pow2(N)? The<br>
| main objection to the constant-time library in LEWG was that we<br>
| weren't sure anyone would use it. Insisting that folks switch from<br>
| operators to functions would increase that risk.<br>
|<br>
| Jeffrey<br>
|<br>
| On Sat, Nov 15, 2014 at 9:15 AM, Jens Maurer <<a href="mailto:Jens.Maurer@gmx.net" class="cremed">Jens.Maurer@gmx.net</a>><br>
| wrote:<br>
| ><br>
| > A preliminary observation: The C++ standard (in contrast to the C<br>
| > standard) does not explicitly prescribe one of two's complement,<br>
| > one's complement, sign-magnitude for signed integer representations,<br>
| > but certainly those three choices are allowed by C++.<br>
| ><br>
| > On 11/14/2014 11:45 PM, Jeffrey Yasskin wrote:<br>
| >> We could suggest that the programmers explicitly multiply by a power<br>
| >> of 2 instead, but they're using the <<s at least partly to get<br>
| >> constant-time operation, and relying on multiplication for this would<br>
| >> depend even more on implementation details than they already are.<br>
| ><br>
| > This seems to rely on two's complement representation for negative<br>
| > numbers, which is (from the standard's perspective) a non-portable<br>
| > assumption.<br>
| ><br>
| > In my opinion, users expecting constant-time operations would be<br>
| > better served with a (small) library that allows them to express their<br>
| > intent, instead of misusing shifts for multiplication. For example,<br>
| > the following would help (after adding a "multiplication-by-power-of-two"<br>
| > function):<br>
| > <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4145.html" target="_blank" class="cremed">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4145.html</a><br>
| ><br>
| >> Separately, a related piece of code uses a signed right-shift to<br>
| >> repeat the sign bit across all the bits of a number:<br>
| >><br>
| <a href="https://boringssl.googlesource.com/boringssl/+/e18d821dfcc32532caeeb1a2" target="_blank" class="cremed">https://boringssl.googlesource.com/boringssl/+/e18d821dfcc32532caeeb1a2</a><br>
| d15090672f592ce3/crypto/internal.h#157.<br>
| >> This is implementation-defined rather than undefined, so the<br>
| >> programmers can probably use #if to check for the behavior they<br>
| >> expect, as at<br>
| >><br>
| <a href="https://github.com/teor2345/tor/blob/ced74e0144e967f838416e6af92cba65" target="_blank" class="cremed">https://github.com/teor2345/tor/blob/ced74e0144e967f838416e6af92cba65</a><br>
| c007d89b/src/ext/curve25519_donna/curve25519-donna.c#L466<br>
| ><br>
| > Well, that's still a bit disappointing, since you get an #error if your<br>
| > compiler doesn't provide the expected semantics.<br>
| ><br>
| > If we can identify a small set of basic operations that people want to<br>
| > use, we should give them a (small) library instead of asking them to do<br>
| > non-portable things.<br>
| ><br>
| >> Is there space to improve the situation here?<br>
| ><br>
| > Yes, but (in my opinion), it's not in the direction of changing the<br>
| > core language for these purposes.<br>
| ><br>
| > Bit-shifts are for unsigned numbers; applying them to signed numbers<br>
| > is a bug, in my opinion.<br>
| ><br>
| > Jens<br>
| > _______________________________________________<br>
| > ub mailing list<br>
| > <a href="mailto:ub@isocpp.open-std.org" class="cremed">ub@isocpp.open-std.org</a><br>
| > <a href="http://www.open-std.org/mailman/listinfo/ub" target="_blank" class="cremed">http://www.open-std.org/mailman/listinfo/ub</a><br>
| _______________________________________________<br>
| ub mailing list<br>
| <a href="mailto:ub@isocpp.open-std.org" class="cremed">ub@isocpp.open-std.org</a><br>
| <a href="http://www.open-std.org/mailman/listinfo/ub" target="_blank" class="cremed">http://www.open-std.org/mailman/listinfo/ub</a><br>
_______________________________________________<br>
ub mailing list<br>
<a href="mailto:ub@isocpp.open-std.org" class="cremed">ub@isocpp.open-std.org</a><br>
<a href="http://www.open-std.org/mailman/listinfo/ub" target="_blank" class="cremed">http://www.open-std.org/mailman/listinfo/ub</a><br>
</div></div></blockquote></div><br></div></div></div></div></div>