Несколько слов о языке C
[несколько слов пропущено, потому что они все нецензурные]
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" следует интерпретировать как "ведёт себя по-разному в соседних строчках кода?"
no subject
Но, да, некрасиво, хоть и неудивительно. а на -Wall что компиляторы говорят?
no subject
no subject
no subject
... но да, если уж undefined и всё так ужасно, то чего мелочиться-то. Что ж, придётся усыпать код омерзительными if-ами.
no subject
no subject
Гы. промежуточное
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 amd64no subject
Не только теперь, но с 1973 года. C language: enabling shooting yourself in the foot for 40 bloody years!
no subject
no subject
no subject
no subject
no subject
no subject
no subject
no subject
no subject
с праздничком тебя! Любви!
no subject
no subject
Ну скорее как "может вести себя по разному в ...". Может стереть данные на диске, сжечь материнскую плату, устроить ядерную войну... А какие еще варианты то?
no subject
no subject
http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
Вот отчёт о его применении к libc++:
http://cplusplusmusings.wordpress.com/2013/03/26/testing-libc-with-fsanitizeundefined/
no subject
no subject
no subject
no subject
no subject
ты, кстати, http://www.amazon.com/gp/product/B009RAOZ8M/ref=docs-os-doi_0 читал?
no subject
читал, кажется; не особо впечатлило, по-моему.
edit: ну то есть понятно, что это требует довольно продвинутой модели target-а при кросс-компиляции; но в собственно порождаемом коде это никакого оверхеда не приносит.
no subject
no subject
no subject
Фактическая инструкция "shll" выполняется только для второго инлайна функции g() в теле main(). Смотри строку 30 в этом фрагменте:
http://codepad.org/XBCaHfIo
Она как раз возвращает стабильный результат.
Вариант без "-O2" честно геренрирует и дважды вызывает функцию g(), которая честно содержит "shll". Наверно это объясняет наблюдаемое поведение.
Для меня загадкой остается то, зачем компилятор сохраняет в коде отдельную реализацию g(), которая никогда не вызывается, но это уже другая тема.
no subject
Это не называется "оптимизирует" -- это баг. Константный шифт на 32, будучи undefined, сочтён nop-ом и несэмичен.
Фактическая инструкция "shll" выполняется только для второго инлайна функции g() в теле main().
Конечно; так и должно быть в случае precomputed vs emitted.
no subject
Очевидно, потому что она не static, и поэтому может вызываться из других файлов, с которыми будет слинкован этот.
no subject