>> uint32_t t1; >> int main(){ >> t1=0xf << (12); // t1 gets fffff000 instead of 0000f000 >> } >> >> > >uint32_t t1; >int main(){ > t1=0xfUL << (12); // t1 gets fffff000 instead of 0000f000 >} >
I'll try to translate :-) : in avr-gcc, the "int" type is 16 bit (rather than 32 bit, which is the standard in the PC world nowadays). The C standard states that constants are by default int (this is not precise, but good enough for our explanation; for more details go to the standard), i.e. your 0xF is 0x000F, signed. Now if you shift it by 12 to the left, you set (among others) the 15-th bit, which is the sign. So your right-hand side expression is 0xF000, but it's not 61440 (which it would be if it would be unsigned int), but it's -4096. At the moment of assignment to a 32-bit unsigned value, a conversion is performed, which is in fact a sign extension - again, for the detailed procedure go to the C standard, and IIRC Derek Jones provides some reasoning why is it so. Now what Eric did was that he converted the very first constant explicitly into unsigned long, which in avr-gcc is equivalent to uint32_t. Since then, the rules are to perform everything in 32-bit arithmetics, which yields the expected result straightforwardly. The keywords for further reading are "integer promotion" and "usual arithmetic conversions". Enjoy! Jan Waclawek (The C-hater) _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org https://lists.nongnu.org/mailman/listinfo/avr-gcc-list