Форум: "Основная";
Текущий архив: 2006.05.07;
Скачать: [xml.tar.bz2];
ВнизRange Check Error Найти похожие ветки
← →
MegaVolt © (2006-03-30 18:02) [0]Почему в первой функции при включенной проверке выхода за границы диапазонов вылазит ошибка а во второй нет
function F1(s:string):cardinal;
begin
Result:=(StrToInt(s) and $FF) shl 24;
end;
function F2(s:string):cardinal;
begin
Result:=(StrToInt(s) shl 24) and $FF000000;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(F1("192")));
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage(IntToStr(F2("192")));
end;
причём если сдвиг делать на меньшее число байт то всё нормально.
← →
MegaVolt © (2006-03-30 18:06) [1]Причём если передать число большее чем байт вторая функция всё равно не ругается хотя за границу cardinal вылам точно.
← →
Pavia © (2006-03-30 22:25) [2]Во второй функции дельфи подставляет
StrToInt(s:string):int64;
А в первой
StrToInt(s:string):integer;
Так что, во второй запас большой.
← →
Германн © (2006-03-31 01:11) [3]
> Pavia © (30.03.06 22:25) [2]
>
> Во второй функции дельфи подставляет
> StrToInt(s:string):int64;
> А в первой
> StrToInt(s:string):integer;
> Так что, во второй запас большой.
Есть StrToInt, а есть StrToInt64. Это две большие разницы. И дельфи врядли сможет сама "подставить" вместо одной другую. Да и не в этой функции дело.
Мне непонятен сам смысл сабжа, в котором присутствует функция and, которая может только уменьшить результат, а никак не увеличить.
← →
Defunct © (2006-03-31 04:28) [4]Конкретно в таких случаях я поступаю так:
{$R-}
Хотя чаще просто выключаю Range Checking вообще в опциях проекта.
И зачем нужен RangeCheck, если я знаю, что мне нужно, а компилятор лишь думает, что я этого не знаю. Проще ставить {$R+} там где есть какая-то неуверенность в коде.
← →
Rouse_ © (2006-03-31 10:00) [5]Тут все очень просто:
Cardinal является у нас unsigned 32-bit, диапазон 0..4294967295
При выполнении данного кода генерируются такие инструкции:mov eax,[ebp-$04]
call StrToInt
mov ebx,eax
and ebx,$000000ff
shl ebx,$18
test ebx,ebx
jns $0049cd2a
call @BoundErr
Вот эти две инструкцииtest ebx,ebx
jns $0049cd2a
проверяют - не является ли полученное число отрицательным, и если оно является таковым - то выполняется BoundErr.
Признак отрицательного значения у нас находиться в флаге SF, который после выполнения инструкции shl ebx,$18 становиться равным единице.
Результат выполнения данной функции равен: -1073741824
Измени обьявление функции на такое: function F1(s:string):Integer;
и ошибка исчезнет :)
← →
Rouse_ © (2006-03-31 10:14) [6]
> И зачем нужен RangeCheck, если я знаю, что мне нужно, а
> компилятор лишь думает, что я этого не знаю. Проще ставить
> {$R+} там где есть какая-то неуверенность в коде.
Вот такой код при отключенной проверке выхода за пределы диапазона приведет к AV, т.к. цикл будет крутиться от нуля до 4294967295var
I: Cardinal;
begin
List.Count := 0;
I := 0 to List.Count - 1 do
begin
ListItems[I] := "qwe";
end;
end;
← →
MegaVolt © (2006-03-31 10:29) [7]>Вот эти две инструкции проверяют - не является ли полученное число отрицательным, и если оно является таковым - то выполняется BoundErr.
А почему не учитывается что наше число впринципе не может быть отрицатеьным. Т.к. cardinal только положителен.
И почему во втором случае корый действительно при сдвиге неизвесно какого числа может привести к переполнению компилятор молчит? Т.е. сдвиг числа большего чем 255 привелёт к переполнению.
← →
Rouse_ © (2006-03-31 10:35) [8]За переполнение отвечает флаг OF. по нему тоже идет проверка...
А почему не учитывается - ну ты нашел у кого спросить :)
Спрашивай у разработчиков компилятора :)
← →
Rouse_ © (2006-03-31 10:38) [9]Ну и в конце концов - если отключена данная проверка, то ты всеравно получишь результат: просто отрицательное значение вычтеца из 4294967295
и получиться число которое соответствует типу Cardinal
← →
MegaVolt © (2006-03-31 11:12) [10]ИМХО ничего там не вычитается :) Просто если смотреть на первый бит как на знаковый то число отрицательное. А если считать число положительным то это и есть положительное число :)
← →
Rouse_ © (2006-03-31 11:15) [11]Ну в принципе да...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.05.07;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.009 c