Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.05.07;
Скачать: CL | DM;

Вниз

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, т.к. цикл будет крутиться от нуля до 4294967295
var
 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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.038 c
15-1144754702
Prohodil Mimo
2006-04-11 15:25
2006.05.07
Вопрос по Mirande


15-1145095256
SergP.
2006-04-15 14:00
2006.05.07
Нужна помощь по скачиванию файла


10-1117622453
Магнум
2005-06-01 14:40
2006.05.07
Экспорт в Excel 2003


3-1142414053
Alex_Delphi
2006-03-15 12:14
2006.05.07
Как импортировать DBF таблицу в базу Oracle 8


2-1145339802
Ярослав
2006-04-18 09:56
2006.05.07
Помогите, не знаю в чем дело