jsn: (common)
[personal profile] jsn

[несколько слов пропущено, потому что они все нецензурные]

jason@jsn c $ cat r.c
#include <stdio.h>

#define B (sizeof(int) * 8)
int _ = B ;
int f(void) { return _ ; }

unsigned g(unsigned x) {
    printf("x == %d, ", x) ;
    return 1 << (B - x) ;
}

int main(int ac, const char *av[]) {
    printf("g(x) == %d\n", g(0)) ;
    printf("g(x) == %d\n", g(B - f())) ;
    return 0 ;
}
jason@jsn c $ gcc -o r r.c && ./r
x == 0, g(x) == 1
x == 0, g(x) == 1
jason@jsn c $ gcc -O2 -o r r.c && ./r
x == 0, g(x) == 0
x == 0, g(x) == 1
jason@jsn c $ clang -o r r.c && ./r
x == 0, g(x) == 1
x == 0, g(x) == 1
jason@jsn c $ clang -O2 -o r r.c && ./r
x == 0, g(x) == 0
x == 0, g(x) == 1
jason@jsn c $ 

Это, что, считается нормально теперь? Там, что, в стандарте действительно сказано, что overflowing left shift result is undefined? И "undefined" следует интерпретировать как "ведёт себя по-разному в соседних строчках кода?"

Date: 2013-02-14 02:43 pm (UTC)
From: [identity profile] ilya-dogolazky.livejournal.com
Ответ на все три вопроса "ну типа да". Ответ "ноль" получен, видимо, прямо во время компиляции, и является "верным" (ну то есть не по правилам языка, а по нашему преставлению о том, сколько будет 1<<32). Ответ "1" честно вычислен микропроцессорной командой сдвига во время исполнения, на i386 процессорах (по крайней мере на некоторых, за все не скажу) длина сдвига берётся только из младших пяти битиков.

Date: 2013-02-14 02:49 pm (UTC)
From: [identity profile] jsn.livejournal.com
Мощно, спасибо. [livejournal.com profile] sgt, впрочем, сообщает, что у него на clang-е:
x == 0, g(x) == 4195907
x == 0, g(x) == 1

... но да, если уж undefined и всё так ужасно, то чего мелочиться-то. Что ж, придётся усыпать код омерзительными if-ами.

Date: 2013-02-14 03:51 pm (UTC)
From: [identity profile] alexott.livejournal.com
у меня на 64-bit линуксе и clang (с -O2, clang 3.0):
x == 0, g(x) == 4195973
x == 0, g(x) == 1

Date: 2013-02-14 03:52 pm (UTC)
From: [identity profile] jsn.livejournal.com
У меня clang 3.2; 4195973 всё ж похоже на баг в clang-е.

Гы. промежуточное

Date: 2013-02-14 04:19 pm (UTC)
From: [identity profile] dmarck.livejournal.com
marck@castor:~/tmp/jsn-shift> clang -O2 -o r r.c && ./r
x == 0, g(x) == 4196043
x == 0, g(x) == 1
marck@castor:~/tmp/jsn-shift> clang --version
FreeBSD clang version 3.1 (branches/release_31 156863) 20120523
Target: x86_64-unknown-freebsd9.0
Thread model: posix
marck@castor:~/tmp/jsn-shift> uname -a
FreeBSD castor.rinet.ru 9.1-STABLE FreeBSD 9.1-STABLE #0 r245742: Mon Jan 21 21:29:07 MSK 2013
     marck@castor.rinet.ru:/usr/obj/usr/src/sys/CASTOR  amd64
Edited Date: 2013-02-14 04:27 pm (UTC)

Profile

jsn: (Default)
jsn

July 2020

S M T W T F S
   1234
56789 1011
12131415161718
19202122232425
262728293031 

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 2nd, 2026 04:16 am
Powered by Dreamwidth Studios