Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1179782454
Meganop
2007-05-22 01:20
2007.06.17
DBImage и как с ним работать


1-1177133804
Залозных Игорь
2007-04-21 09:36
2007.06.17
Файл как параметр функции


2-1180357302
ZevSS
2007-05-28 17:01
2007.06.17
торможу что-то... progressbar waitinggradient


8-1159138130
Brandik
2006-09-25 02:48
2007.06.17
Как тупо, банально рисовать на форме


6-1164800741
Term
2006-11-29 14:45
2007.06.17
вопрос по TServerSocket





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский