|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Delphi XE, не работают циклы
Добрый день!
Использую в работе Delphi XE, всё хорошо и вот недавно возникла проблема перестали работать некоторые циклы. Проект большой, суть его в том имеется таблица значений, столбцов порядка 30, а строк может быть много, от единиц до десятков и сотен тысяч. Строки обрабатываются в циклах и вот некоторые из этих циклов, при количестве итераций больше 32597 строк, перестали работать, то есть программа их просто проскакивает, при этом никаких условий перед циклом нет. Так-же заметил что в некоторых случаях такое возникало когда цикл был не от 0, но тем не менее первое значение цикла было меньше конечного: Код:
procedure SomeProc(FirstRow, LastRow: integer);{FirstRow заведомо меньше LastRow} var i: integer; begin {Некоторые начальные операции, которых может и не быть} for i := FirstRow to LastRow do begin {операции со строкой i} end; end; Временное решение было таким: Код:
procedure SomeProc(FirstRow, LastRow: integer);{FirstRow заведомо меньше LastRow} var i, j: integer; begin {Некоторые начальные операции, которых может и не быть} for j := 0 to (LastRow - FirstRow) do begin i := FirstRow + j; {операции со строкой i} end; end; В итоге цикл работает при количестве итерации большем 32597. Но был и случай когда цикл уже был от 0: Код:
procedure SomeProc;{FirstRow заведомо меньше LastRow} var i: integer; begin {Некоторые начальные операции, которых может и не быть} for i := 0 to RowCount - 1 do begin {операции со строкой i} end; end; В этом случае, сделал так: Код:
procedure SomeProc;{FirstRow заведомо меньше LastRow} var i, j: integer; begin {Некоторые начальные операции, которых может и не быть} for j := 0 to RowCount - 1 do begin i := j; {операции со строкой i} end; end; И цикл начал работать. При замене цикла на цикл while всё работает. Оптимизация отключена глобально. В чём тут может быть проблема? |
#2
|
|||
|
|||
Проблема в Delphi XE - все творения Embarcadero заметно проигрывают более ранним версиям в стабильности и скорости. Почему в такой ситуации Embarcadero продолжает накручивать разные плюшки (вообщем-то интересные, но не ценой же стабильности) и выпускать все новые и новые версии, а не отлавливает баги уже существующих версий - вопрос к ним (наверное это торжество маркетинга над программингом ). Но то что RAD Studio со сложными проектами превращается в глюкозавра - печальный факт. Решение - или подстраиваться под баги (что вы и продемонстрировали) или уйти на стабильную версию (а вы думаете почему в сети до сих пор бродит так много сборок Delphi 7, а кое-где до сих пор продается в качестве отдельного продукта; лицензия на Delphi 7 дается вместе с RAD Studio?)
Последний раз редактировалось Lucky192, 10.10.2011 в 16:06. |
#3
|
|||
|
|||
Воспроизвел ошибку на тестовом проекте, вынес в класс:
Код:
TError = class private function Add(FromV, ToV: Integer): Integer; function Check(Row: Integer; Val: Byte): Boolean; function Operation(Index: Integer; Func: TFunc<Integer,Integer>): Integer; public function Run(Count: Integer): Integer; end; function TError.Add(FromV, ToV: Integer): Integer; var i: Integer; res: Integer; func: TFunc<Integer,Integer>; begin res := 0; func := function(data: Integer): Integer begin if Check(i, MAXBYTE div 2) then Result := data; end; for i := FromV to ToV do res := Operation(i, func); Result := res; end; function TError.Check(Row: Integer; Val: Byte): Boolean; begin Result := True; end; function TError.Operation(Index: Integer; Func: TFunc<Integer, Integer>): Integer; begin if Assigned(Func) then Result := Func(Index); end; function TError.Run(Count: Integer): Integer; begin Result := Add(0, Count); end; В результате получаем, если:
Если реализацию анонимного метода вынести в отдельный метод, тогда всё работает как надо. Если условие Check сделать без параметров, тогда будет всё работать и с анонимным методом. Либо я что-то делаю не так, либо это баг в Delphi XE, если это так, то стоит ли отправлять это на сайт Эмбаркадеро? |
#4
|
||||
|
||||
Вообще меня смущает ваша цифра 32767. Складывается впечатление, что по неведомым причинам у вас в цикле используется 2 байтный счетчик, а не 4 байтный. А что если счетчик определить не как Integer, а как DWord?
Жизнь такова какова она есть и больше никакова. Помогаю за спасибо. |
#5
|
|||
|
|||
Тут именно баг компилятора, вот такой код он генерирует для цикла:
Код:
0040F8D0 FF400C inc dword ptr [eax+$0c] Test.dpr.32: for i := FromV to ToV do 0040F8D3 8B45E0 mov eax,[ebp-$20] 0040F8D6 8B400C mov eax,[eax+$0c] 0040F8D9 663B45E6 cmp ax,[ebp-$1a] 0040F8DD 7ED7 jle $0040f8b6 {переход на тело} и тут действительно счётчик 16 битный. Готовлю отчет в QualityCentral. |
#6
|
|||
|
|||
Запостил отчёт:
http://qc.embarcadero.com/wc/qcmain.aspx?d=99909 Проголосуйте, если есть возможность. |