Столкнулся с подобной ерундой:
На FreeBSD 4.8R (родной компилятор) следующий код:#include <stdio.h>
int main() {
unsigned long addr=4000000000LU;
unsigned char mask=0;printf ("%lu\n",addr&(0xffffffff<<(32-mask)));
}дает результат: 4000000000 (что не правильно!), если в printf'е поставить руками 0:
#include <stdio.h>
int main() {
unsigned long addr=4000000000LU;
unsigned char mask=0;printf ("%lu\n",addr&(0xffffffff<<(32-0)));
},то результат: 0
Turbo C 2.0 досовский правильно справляется с этой ситуацией.
> unsigned long addr=4000000000LU;
> unsigned char mask=0;
>
> printf ("%lu\n",addr&(0xffffffff<<(32-0)));
>,то результат: 0
Не должно быть результата вовсе.
Оператор сдвига 0xffffffff << 32 не корректен.
0xffffffff можно сдвинуть только на 31 бит, но не дальше.
>> unsigned long addr=4000000000LU;
>> unsigned char mask=0;
>>
>> printf ("%lu\n",addr&(0xffffffff<<(32-0)));
>>,то результат: 0
>Не должно быть результата вовсе.
>Оператор сдвига 0xffffffff << 32 не корректен.
>0xffffffff можно сдвинуть только на 31 бит, но не дальше.
printf ("%lu\n",addr & (((u_int64_t)0xffffffff) << (32-0)));
тогда сдвинется
>Столкнулся с подобной ерундой:
>На FreeBSD 4.8R (родной компилятор) следующий код:
>
>#include <stdio.h>
>
>int main() {
> unsigned long addr=4000000000LU;
> unsigned char mask=0;
>
> printf ("%lu\n",addr&(0xffffffff<<(32-mask)));
>}
>
>дает результат: 4000000000 (что не правильно!), если в printf'е поставить руками 0:
>
>
>#include <stdio.h>
>
>int main() {
> unsigned long addr=4000000000LU;
> unsigned char mask=0;
>
> printf ("%lu\n",addr&(0xffffffff<<(32-0)));
>}
>
>,то результат: 0
>
>Turbo C 2.0 досовский правильно справляется с этой ситуацией.
в первом случае компилятором генерируется команда shl, которая сдвигает регистр eax на 32 бита вправо
но начиная с 286 проца эта команда использует только 5 младших битов счетчика, остальные игнорируются
так что для процессора это все равно что сдвигать на 0 битво втором случае, так как в скобках стоит константа, компилятор видит проблему, дайт warning, и подставляет просто 0 в качестве результата, вообще ничего не высчитывая