URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 2080
[ Назад ]

Исходное сообщение
"Не понимаю ..."

Отправлено Alexander , 17-Сен-03 13:43 
Столкнулся с подобной ерундой:
На 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 досовский правильно справляется с этой ситуацией.


Содержание

Сообщения в этом обсуждении
"Не понимаю ..."
Отправлено SergeiZz , 18-Сен-03 13:09 
> unsigned long addr=4000000000LU;
> unsigned char mask=0;
>
> printf ("%lu\n",addr&(0xffffffff<<(32-0)));
>,то результат: 0
Не должно быть результата вовсе.
Оператор сдвига 0xffffffff << 32 не корректен.
0xffffffff можно сдвинуть только на 31 бит, но не дальше.


"Не понимаю ..."
Отправлено aka50 , 23-Сен-03 17:01 
>> 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)));
тогда сдвинется


"Не понимаю ..."
Отправлено qq , 23-Сен-03 20:38 
>Столкнулся с подобной ерундой:
>На 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 в качестве результата, вообще ничего не высчитывая