B
British0zzy
Is it a defined operation when I do something like this:
char a = 15;
a = a<<9;
char a = 15;
a = a<<9;
Richard said:British0zzy said:
Only on systems where char has at least 10 bits.
The relevant Standard cite is 3.3.7 Bitwise shift operators:
"If the value of the right operand is negative or is greater than or equal
to the width in bits of the promoted left operand, the behavior is
undefined."
British0zzy said:Is there any system out there which will not zero out all the bits?
Yes.
nate@archdiocese:/tmp$ uname -a
Linux archdiocese 2.6.23 #2 PREEMPT Fri Jan 25 19:38:09 PST 2008 i686 GNU/Linux
nate@archdiocese:/tmp$ gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.2-1' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-cld --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.3.2 (Debian 4.3.2-1)
nate@archdiocese:/tmp$ cat s2.c
#include <stdio.h>
unsigned int shift(unsigned int a, unsigned int c) { return a << c; }
int main(void) {
printf("%d\n", shift(5, 40));
return 0;
}
nate@archdiocese:/tmp$ gcc s2.c
nate@archdiocese:/tmp$ ./a.out
1280
nate@archdiocese:/tmp$ gcc -O2 s2.c
nate@archdiocese:/tmp$ ./a.out
0
For those not familiar with the 386 and its successors, unsigned int
is 32 bits.
The 386 provides an instruction which shifts a 32-bit register. The
count of bits to shift is contained in an 8-bit register. In order
not to do an unnecessary amount of shifting, the instruction masks off
the highest 3 bits of the count to get a value between 0 and 31. gcc
implements the << operator directly in terms of this instruction, so
the same phenomenon appears. The only way to avoid it would be by
generating a test whether the count was greater than 32, which would
require an extra compare and conditional jump and be a lot less
efficient. So gcc takes advantage of the fact that "undefined
behavior" allows it to use the native instruction's behavior.
With optimization on, gcc is able to compute the result of the shift
at compile time, and does it the "right" way.
The same effect doesn't appear with char on this platform, but you get
the idea.
^^^^^^^^Richard Heathfield said:British0zzy said:
Only on systems where char has at least 10 bits.
The relevant Standard cite is 3.3.7 Bitwise shift
operators:
"If the value of the right operand is negative or is
greater than or equal to the width in bits of the
promoted left operand, the behavior is undefined."
British0zzy said:Is there any system out there which will not zero out
all the bits?
Eric Sosman said:...The value of CHAR_BIT affects the outcome because
it affects the value of CHAR_MAX used in the conversion,
but it does not affect the operation of or validity of
the shift.
... changing the second line to `int i = a << 9;'
yields a fragment whose behavior is the same on all
implementations.
British0zzy said:Is it a defined operation when I do something like this:
char a = 15;
a = a<<9;
CBFalconer said:That depends on the value of MAX_CHAR.
Jack Klein said:What exactly do you mean by "promote to a narrower int"?
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.