Форум: "Начинающим";
Текущий архив: 2007.06.17;
Скачать: [xml.tar.bz2];
ВнизОшибка компилятора Delphi или просто особенность?? Найти похожие ветки
← →
vpbar (2007-05-28 11:32) [0]Приветствую. Вопрос знатокам.
Есть такой код:
var index:Cardinal;// or j:DWORD
s:string;
l:TList;
begin
l:= TList.Create;
s:="";
for index:=0 to l.Count-1 do
s:=s+" "+inttostr(Integer(L.Items[index]));
caption:=s;
l.free;
end;
Логично что если список пуст, то тело цикла не выполнится?
Ан нет. При выполнении вылетает ошибка. Пройдясь отладчиком видим, выполняется цикл, где идет обращение к 0-му элементу пустого списка, что естественно вызывает ошибку.
В отладчике видим что начало цикла компилируется в
mov ebx, TList.Count
dec ebx
test ebx,ebx
jb @@ВыходИзЦикла
......
Вспоминаем: JB/JNAE Перейти, если меньше / перейти, если не больше или равно CF = 1
соответсвенно этот переход не будет выполнен ( test обнуляет CF) и идем в цикл, что вызовет ошибку.
Если же мы объявим var index:integer; то все ок.
Начала цикла при этом изменится
mov ebx, TList.Count
dec ebx
test ebx,ebx
jl @@ВыходИзЦикла //!!!!!!!
.............
При этом переход JL сработает и мы не полезем в цикл, т.е. все ок.
Вообще, если index беззнаковый тип - то будет ошибка.
Собственно вот в чем вопрос: это поведение является нормальным или это ошибка компилятора? По крайней мере в документации я об этом ничего не встречал.
← →
MBo © (2007-05-28 11:41) [1]если Range check error включить, будет ошибка.
проблема не в цикле, а в неявном приведении Dword(- 1) = $FFFFFFFF
← →
Rouse_ © (2007-05-28 11:46) [2]т.е. просто смени у index тип на Integer
← →
vpbar (2007-05-28 14:13) [3]>>Rouse_
Дык решение то я нашел.
Просто интересно, это баг или фича. Документировано или я просто не нашел, ничего об этом.
>>MBo
Действительно, ну хоть что-то. Хотя лучше если б при компиляции ругался.
← →
DrPass © (2007-05-28 16:06) [4]
> Просто интересно, это баг или фича. Документировано или
> я просто не нашел, ничего об этом.
Это фича - по правилам при сравнении знаковых и беззнаковых типов оба операнда приводятся к беззнаковым. Другое дело, что хинт в такой ситуации вполне пригодился бы...
← →
Barloggg (2007-05-28 16:16) [5]i.count = 0
значит i.count-1 должно быть равным -1
а dword от минус единицы это много много в плюс
но с другой стороны цикл-то получается от 0 до -1.
так что это компилятор.
он сначала преобразовывает оба значения (начальное и конечное) в Dword а потом запускает цикл.
если бы он в своих переменных держал эти значения, а потом уже при запуске цикла выдавал бы текущее значение таких проблем не было бы вообще. но это же надо еще додуматься, верно?
в общем это не совсем глюк, а скорее "особенность" компилятора.
← →
ANB © (2007-05-28 16:32) [6]Не знаю, не знаю. У меня делфи 7 обычно ругалась при попытке неаккуратно работать с Cardinal. Но тоже не всегда. Да и в конце концов - откуда компилятор знает, что в беззнаковую переменную заранее было загружено такое здоровое число ?
← →
vpbar (2007-05-28 17:06) [7]>>ANB
Дело в том что если есть цикл for index:=0 to Count do Где index:DWORD a Count:Integer то, тут компилятор знает типы и должен бы ругнуться про попытку присвоить знаковое значение беззнаковому.
Хотя Делфи вообще ,видимо, не считает такое присовоение ошибочным. Единственное что остается ставить Range check error и ловить ошибки в рантайме. Ну и смотреть внимательней на такие переменные.
Ну если значения приводятся к беззнаковым, то ,видимо, действительно фича. Хоть лучше бы при этом он ругнулся.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.06.17;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.053 c