On Fri, 11 Apr 2008 15:33:41 CST, Olivier Langlois
<olanglois@sympatico.ca> 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 document, 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 shift operator so
unintuitive.
The shift operator mimics the underlying behavior of the hardware,
which differs on various architectures. This is exactly the same
reason that right shifting 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 shift value before it goes
to the shifter hardware. When shifting a 32-bit register, they mask
the shift argument with 0x1f. This is especially true of processors
with barrel shifters that can shift by any number in a single cycle,
instead of one cycle per bit shifted.
when it really took one clock per shifted position.
Consider what that would do to the interrupt response time. :-)
[ comp.lang.c++.moderated. First time posters: Do this! ]