Несколько слов о языке C
Feb. 14th, 2013 05:58 pm[несколько слов пропущено, потому что они все нецензурные]
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
Date: 2013-02-15 01:09 am (UTC)no subject
Date: 2013-02-17 03:53 am (UTC)Фактическая инструкция "shll" выполняется только для второго инлайна функции g() в теле main(). Смотри строку 30 в этом фрагменте:
http://codepad.org/XBCaHfIo
Она как раз возвращает стабильный результат.
Вариант без "-O2" честно геренрирует и дважды вызывает функцию g(), которая честно содержит "shll". Наверно это объясняет наблюдаемое поведение.
Для меня загадкой остается то, зачем компилятор сохраняет в коде отдельную реализацию g(), которая никогда не вызывается, но это уже другая тема.
no subject
Date: 2013-02-18 09:13 am (UTC)Это не называется "оптимизирует" -- это баг. Константный шифт на 32, будучи undefined, сочтён nop-ом и несэмичен.
Фактическая инструкция "shll" выполняется только для второго инлайна функции g() в теле main().
Конечно; так и должно быть в случае precomputed vs emitted.
no subject
Date: 2013-02-18 09:51 am (UTC)Очевидно, потому что она не static, и поэтому может вызываться из других файлов, с которыми будет слинкован этот.
no subject
Date: 2013-02-18 02:55 pm (UTC)