--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/95e94b53-d65a-4a81-8209-9ec5322d09d7%40isocpp.org.
Hi Matthew,I am interested in a similar feature specifically related to arithmetic scaling (although I'm not completely certain of its necessity yet). However, it has a number of extra requirements. Notably, I'd like for users to be able to specialize scaling for their own, user-defined types. I'd also like to consider powers other than two.
The upshot of these two requirements would be classes in the style of std::hash with an additional parameter specifying the base. For example:// standardtemplate<Integral T, int Base>struct shar;// user-definedtemplate<>struct shar<MyIntegralType, 2> {
constexpr MyIntegralType operator()(const MyIntegralType& x, int s);
}How palatable does all this sound? I'm in two minds whether this should be something to consider in your proposal or merely something that would depend upon it for standard specializations involving built-in types.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5b7d2c28-ffed-44f5-b19d-2d906f57a09a%40isocpp.org.
On 10/11/16 07:50, Matthew Fioravante wrote:
> As suggested in the other thread about 2's complement, and also lifted
> from my previous proposal N3864. I've written a small proposal to add
> explicit shift operations to the standard library.
>
> Should be pretty self explanatory.
>
> https://github.com/fmatthew5876/stdcxx-bitops/blob/master/proposal/shift.md
>
> Please let me know if you have any objections or feedback.
I'm interested in this proposal and I have a few suggestions.
1. I think it would be better to reverse the letters that denote
left/right and logical/arithmetic shift. I.e. rename shlr -> shrl and
shar -> shra.
2. With the above naming change, add a new function shr(), which will be
equivalent to shra for signed types and shrl for unsigned. I think, this
is the "natural" shift that most developers expect and compilers
implement for operator>>. I would even say, this would be the most
useful shift function.
3. With the above naming change, it might be reasonable to also rename
shll -> shl since there is no arithmetic left shift anyway.
4. Use unsigned int for bit count. Yes, I know the committee members
announced the preference for signed types, but using a signed type and
immediately saying it must never have negative values is just nonsense, IMO.
On quarta-feira, 26 de outubro de 2016 17:18:39 PDT Matthew Fioravante wrote:
> > 1. I think it would be better to reverse the letters that denote
> > left/right and logical/arithmetic shift. I.e. rename shlr -> shrl and
> > shar -> shra.
>
> I like your names better. We usually say SHift Right Arithmetic instead of
> SHift Arithemetic Right.
Another option is to move to the beginning: Logical Shift Right (LSHR or LSR),
Arithmetic Shift Left (ASL), etc. This is what ARM assembly does.
Any way you choose, you're going to find an assembly with different mnemonics.
It's a matter of how many people you're going displease. Just try to choose
something that doesn't cause confusion: it should be unambiguous whether the
shift is to the left or to the right.
> > 3. With the above naming change, it might be reasonable to also rename
> > shll -> shl since there is no arithmetic left shift anyway.
>
> Seems reasonable to me. Although shl() is actually redundant so maybe I
> should remove it. We only really need the right shifts.
Actually, no. Shifting left into the sign bit of a signed integer is undefined.
So this function may still be useful.
> > 4. Use unsigned int for bit count. Yes, I know the committee members
> > announced the preference for signed types, but using a signed type and
> > immediately saying it must never have negative values is just nonsense,
> > IMO.
>
> Thats a philosophical question. Honestly I really don't care whether its
> signed or unsigned.
It might be useful to shift in the other direction if the count is negative.
That would imply a difference in arithmetic and logical shifts left, since
they could go right too.
Subtle wording of 5.9 [expr.shift]/2, that says:
"Otherwise, if E1 has a signed type and non-negative value, and E1 × 2^E2 is
representable in the corresponding unsigned type of the result type, then that
value, converted to the result type, is the resulting value; otherwise, the
behavior is undefined."
1 << 31 implies 1 * 2^31 = 2147483648, which is not representable in int,
therefore it's undefined to shift into the sign bit.
Sorry for missing the beginning of the discussion, but what is the plan for
when the shift count is larger than the type's size? That's UB in the standard
for the built-in operators.
Em quinta-feira, 27 de outubro de 2016, às 19:06:56 PDT, Chris Hallock
escreveu:
> > Subtle wording of 5.9 [expr.shift]/2, that says:
> >
> > "Otherwise, if E1 has a signed type and non-negative value, and E1 × 2^E2
> > is
> > representable in the corresponding unsigned type of the result type, then
> > that
> > value, converted to the result type, is the resulting value; otherwise,
> > the
> > behavior is undefined."
> >
> > 1 << 31 implies 1 * 2^31 = 2147483648, which is not representable in int,
> > therefore it's undefined to shift into the sign bit.
>
> To nitpick, you can (since C++14
> <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1457>)
> left-shift into the sign bit, but not past it. However, the resulting value
> is implementation-defined. Assuming 32-bit ints, 1 << 31 is equivalent to
> static_cast<int>(2147483648) because 1 * 2^31 "is representable in the
> corresponding unsigned type of the result type" (i.e. unsigned int).
Hmm... you're actually right. The resolution of CWG1457 is already in the text
I quoted.
So it isn't UB, it's implementation-defined behaviour.