опубликован 07-01-2002 13:28 MSK
Сидел я тут ваял на вижуальнике
Бах = в пятый раз напоролся на старые грабли
в смысле на баги компилятора= все время о них забываюВот и решил написать сей текстовичок
может кому поможет избежать night debug sessions
Баг 1. компилятор не умеет сдвигать биты больше чем есть в источнике
точнее будет сказать что shr shl sal sar просто игнорируют старшие биты
(WORD)i<<17-не работает= точнее работает но неправильно= сдвигает на 1 бит влево
(DWORD)i<<32- аналогично= вообще не сдвигает
Баг 2.особо мерзкий и зловредный баг
(__int64) не сдвигает больше чем на 31 бит
(__int64)<<34 -будет еще хуже =см команды shld shrd
типичный пример
DWORD i,j,k
k=i*j/0x100000000; //эта злыдня оптимизирут деление на степень 2 как сдвиг
или
k=(i*j)>>32; //LOL
Баг 3. вот уж не знаю кого охаять MS или Intel
после особо премудрых оптимизаций
(__int64)j<<i может выглядеть как shld ecx,eax,cl
вы думаете это работает?
О да....разве что только GPF не генерит
в ecx после такого полный бред содержится
Баг 4. Не используйте знаковые типы
пример
LPSTRUCT lpstruct;
LPSTR lpstr="........."
DWORD i;
.......
lpstruct+(*(lpstr+i))
в чем баг?
да в том что char знаковый
мы имеем преобразование (char) to (DWORD)
movsx ax,[esi+i]
т.е если в строке символ 'я'=0xFF то в ax будет 0xFFFF
не не не это еще не все
дальше еще интереснее
пишем явное преобразование типов
lpstruct+(*((BYTE*)(lpstr+i)))
gy-gy-gy про себя хохочет компилятор
плевать он хотел на какие-то там лишние скобки
снова movsx ax,[esi+i]
Баг 5.
DWORD sim,size,i;
_asm{
mov eax,sim //ругается на SI
mov eax,size //ругается на SI
mov eax,i //нормально
}
Баг 6. не используйте модели вызовов без очистки стека
void Func(DWORD i)
{
while(i>0)
{
.....
i--;
}
}
ох и дрянной баг
в большинстве функций неудобно создавать зеркальные переменные-параметры
вроде DWORD _i=i;
проблема в том что в Debug версии С обычно использует STDCALL
или по крайней мере стек заполняет для каждого вызова заново
а в Release версиях прога сразу начинает глючить
Баг 7. это вообще из области маразмов
_asm{
movd eax,[esi]
}
ЭТО ГАДСТВО КОМПИЛИТСЯ!!!!!
но компилится как movd mm0,[esi]
Баг 8. чудеса оптимизации
for(..;..;..)
{
Foo(0);
Foo(0);
Foo(0);
}
в Release версии Foo(0) ВЫЗОВЕТСЯ ТОЛЬКО 1 РАЗ!!!
а может она где-то глобальные переменные мучает?