Jack Klein wrote:
> On Fri, 11 Apr 2008 15:33:41 CST, Olivier Langlois
> <olanglois@[EMAIL PROTECTED]
> wrote in comp.lang.c++.moderated:
>
>> Hi,
>>
>> I was expecting:
>>
>> int main( int argc, char *argv[] )
>> {
>> unsigned char m = 32;
>> register unsigned mask = (1<<m);
>> std::cout << std::hex << mask << '\n';
>> return 0;
>> }
>>
>> to print 0 but instead this program compiled with g++ prints 1!
>>
>> If I change (1<<m) by (1<<32) or if change the program for
>>
>> int main( int argc, char *argv[] )
>> {
>> unsigned char m = 31;
>> register unsigned mask = (1<<m)<<1;
>> std::cout << std::hex << mask << '\n';
>> return 0;
>> }
>>
>> it gives me the expected 0.
>>
>> In the C++ standard do***ent, section 5.8. It is written "The
>> behavior is undefined if the right operand is negative, or greater
>> than or equal to the length in bits of the promoted left operand."
>>
>> The root for this behavior probably originates from C but I am
>> really curious why the standard makes the ****ft operator so
>> unintuitive.
>
> The ****ft operator mimics the underlying behavior of the hardware,
> which differs on various architectures. This is exactly the same
> reason that right ****fting negative signed values and signed value
> overflow have undefined results, namely because what the underlying
> hardware does can be different.
>
> Nowadays, most modern processors mask the ****ft value before it goes
> to the ****fter hardware. When ****fting a 32-bit register, they mask
> the ****ft argument with 0x1f. This is especially true of processors
> with barrel ****fters that can ****ft by any number in a single cycle,
> instead of one cycle per bit ****fted.
Yes, but on x86 hardware the masking was actually introduced at a time
when it really took one clock per ****fted position.
Consider what that would do to the interrupt response time. :-)
Bo Persson
--
[ See http://www.gotw.ca/resources/clcm.htm
for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


|