LINUX.ORG.RU

Побитовый сдвиг


0

2

Кто-ть может объяснить почему получаются разные результаты ?

  unsigned int ui = 0x80000000;
  uint32_t mask = ui << 1;
  printf("DEBUG %x\n", mask);

  unsigned int ui2 = 0xFFFFFFFF;
  uint32_t mask2 = ui2 << 32;
  printf("DEBUG %x\n", mask2);

А почитать, что пишет компилятор никак? А gcc ведь всё объясняет

HNO-Arzt_
()

Потому что интеловские мануалы читать нужно. Ну или хотя бы K&R. Ну или хотя бы выхлоп компилятора.

d ★★★★★
()
Ответ на: комментарий от d

Потому что интеловские мануалы читать нужно

Как раз их - в самую последнюю очередь, потому что C++ кросс-платформенный язык и Intel ему совершенно не упал. Из них можно понять почему UB в данном случае ведёт себя именно так, но всё равно оно остаётся UB и прежде всего надо понять именно это.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Соглашусь, мануалы следует читать если хочется знать, откуда это взялось и почему решили сделать именно так.

ТС, читай K&R: A.7.8 — Shift Operators

d ★★★★★
()

K&R: The result is undefined if the right operand is negative, or greater than or equal to the number of bits in the left expression's type.

dvl36
()
Ответ на: комментарий от slovazap

Почему это? Если не изменяет память асмовские команды SHL/SHR при сдвиге больше чем на размер разрядной сетки равноценно сдвигу на N mod 32/64

anonymous
()
Ответ на: комментарий от anonymous

Почему это?

асмовские команды

Потому что ТС пишет не на асме, а на C?

d ★★★★★
()
Ответ на: комментарий от anonymous

Ещё один равноценный идиот.

anonymous
()

Я что то не понял: месяц побитовых сдвигов на ЛОРе, или это новый мейнстрим?
//предполагаю из за разницы величины сдвига и размера uint32_t

comp00 ★★★★
()
Ответ на: комментарий от anonymous

Почему это? Если не изменяет память асмовские команды SHL/SHR при сдвиге больше чем на размер разрядной сетки равноценно сдвигу на N mod 32/64

Пара подсказок для тех кто в танке:

  • SHL/SHR есть только на одном единственном семействе процессоров.
  • Компилятор совершенно не обязан компилировать сдвиги именно в SH[LR]

Постарайтесь запомнить: UB - это только UB.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

SHL/SHR есть только на одном единственном семействе процессоров.

на других вроде тоже есть аналоги. Не?

Компилятор совершенно не обязан компилировать сдвиги именно в SH[LR]

с этим согласен. В данном случае компилятор это вообще во время компиляции считает, и в коде там тупо ответ.

00000000004004b0 <main>:
  4004b0:	48 83 ec 08          	sub    rsp,0x8
  4004b4:	31 f6                	xor    esi,esi
  4004b6:	bf 1c 07 40 00       	mov    edi,0x40071c
  4004bb:	31 c0                	xor    eax,eax
  4004bd:	e8 ce ff ff ff       	call   400490 <printf@plt>
  4004c2:	31 f6                	xor    esi,esi
  4004c4:	bf 1c 07 40 00       	mov    edi,0x40071c
  4004c9:	31 c0                	xor    eax,eax
  4004cb:	e8 c0 ff ff ff       	call   400490 <printf@plt>
  4004d0:	31 c0                	xor    eax,eax
  4004d2:	48 83 c4 08          	add    rsp,0x8
  4004d6:	c3                   	ret    

Постарайтесь запомнить: UB - это только UB.

++

drBatty ★★
()
Ответ на: комментарий от anonymous

если библиотеку добавить результаты изменятся?

до последнего веришь в чудо?

false ★★★★★
()
Ответ на: комментарий от drBatty

В данном случае компилятор это вообще во время компиляции считает, и в коде там тупо ответ.

Да, в последнее время какая-то распространенная практика. Нужно подсовывать данные ввода чтоб оптимизатор не на*бал.

dvl36
()
Ответ на: комментарий от dvl36

Да, в последнее время какая-то распространенная практика.

ага. В последние 10 лет.

drBatty ★★
()
Ответ на: комментарий от drBatty

на других вроде тоже есть аналоги. Не?

Возможно есть, возможно нет. Если есть, с какой стати им работать также как на x86? Могут обнулять при сдвиге >= размера операнда, могут брать младшие биты сдвига, могут поднимать исключение, что угодно.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

с какой стати им работать также как на x86?

с какой стати иначе? Никто специально не будет делать «другую» систему команд.

Хотя в данном случае это не играет никакой роли:

$ gcc -Wall tt.c; ./a.out 
tt.c: В функции «main»:
tt.c:11:2: предупреждение: величина сдвига влево больше или равна ширине данного типа [по умолчанию включена]
DEBUG 0
DEBUG ffffffff
$ gcc -O2 -Wall tt.c; ./a.out 
tt.c: В функции «main»:
tt.c:11:2: предупреждение: величина сдвига влево больше или равна ширине данного типа [по умолчанию включена]
DEBUG 0
DEBUG 0

явный быдлокод, т.к. он даёт разные результаты в одних и тех же условиях(разница только в оптимизации, если кто не понял)

drBatty ★★
()
Ответ на: комментарий от drBatty

с какой стати иначе? Никто специально не будет делать «другую» систему команд

Всё равно наоборот, никто специально не будет повторять особенности поведения x86 в граничных случаях.

Вот пруф:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHDDCIF...

на ARM регистр обнулится.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

недопроцессоры никого не интересуют

anonymous
()
Ответ на: комментарий от slovazap

ладно, убедил. Лично я никогда в эту НЁХ и не вдавался.

drBatty ★★
()
Ответ на: комментарий от slovazap

Причём тут АРМ и причём тут регистр, чепушила? Думаешь если сдвинуть не циклически регистр на любом-арме-не-арме на число бит, большее чем регистр может содержать, то может получиться что-то отличное от нуля, дебилушка?

СИ не знают, а всё туда же - в ЛИСП, в АРМы! Шибко умными себя считають.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.