Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Разное
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 10.10.2011, 15:11
DARKShadow DARKShadow вне форума
Прохожий
 
Регистрация: 10.10.2011
Сообщения: 4
Репутация: 10
Печаль 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  
Старый 10.10.2011, 16:03
Lucky192 Lucky192 вне форума
Прохожий
 
Регистрация: 04.10.2011
Сообщения: 28
Репутация: 1351
По умолчанию

Проблема в Delphi XE - все творения Embarcadero заметно проигрывают более ранним версиям в стабильности и скорости. Почему в такой ситуации Embarcadero продолжает накручивать разные плюшки (вообщем-то интересные, но не ценой же стабильности) и выпускать все новые и новые версии, а не отлавливает баги уже существующих версий - вопрос к ним (наверное это торжество маркетинга над программингом ). Но то что RAD Studio со сложными проектами превращается в глюкозавра - печальный факт. Решение - или подстраиваться под баги (что вы и продемонстрировали) или уйти на стабильную версию (а вы думаете почему в сети до сих пор бродит так много сборок Delphi 7, а кое-где до сих пор продается в качестве отдельного продукта; лицензия на Delphi 7 дается вместе с RAD Studio?)

Последний раз редактировалось Lucky192, 10.10.2011 в 16:06.
Ответить с цитированием
  #3  
Старый 11.10.2011, 12:27
DARKShadow DARKShadow вне форума
Прохожий
 
Регистрация: 10.10.2011
Сообщения: 4
Репутация: 10
По умолчанию

Воспроизвел ошибку на тестовом проекте, вынес в класс:

Код:
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;

В результате получаем, если:
  • Count < 32767, то Run < 32767
  • Count = 32767, то программа зависает (видимо цикл бесконечный получается)
  • Count > 32767, то Run = 0 (цикл внутри не выполняется ни разу)

Если реализацию анонимного метода вынести в отдельный метод, тогда всё работает как надо. Если условие Check сделать без параметров, тогда будет всё работать и с анонимным методом.

Либо я что-то делаю не так, либо это баг в Delphi XE, если это так, то стоит ли отправлять это на сайт Эмбаркадеро?
Ответить с цитированием
  #4  
Старый 11.10.2011, 15:26
Аватар для Страдалецъ
Страдалецъ Страдалецъ вне форума
Гуру
 
Регистрация: 09.03.2009
Адрес: На курорте, из окна вижу теплое Баренцево море. Бррр.
Сообщения: 4,721
Репутация: 52347
По умолчанию

Вообще меня смущает ваша цифра 32767. Складывается впечатление, что по неведомым причинам у вас в цикле используется 2 байтный счетчик, а не 4 байтный. А что если счетчик определить не как Integer, а как DWord?
__________________
Жизнь такова какова она есть и больше никакова.
Помогаю за спасибо.
Ответить с цитированием
  #5  
Старый 11.10.2011, 15:54
DARKShadow DARKShadow вне форума
Прохожий
 
Регистрация: 10.10.2011
Сообщения: 4
Репутация: 10
По умолчанию

Тут именно баг компилятора, вот такой код он генерирует для цикла:

Код:
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  
Старый 11.10.2011, 16:30
DARKShadow DARKShadow вне форума
Прохожий
 
Регистрация: 10.10.2011
Сообщения: 4
Репутация: 10
По умолчанию

Запостил отчёт:

http://qc.embarcadero.com/wc/qcmain.aspx?d=99909

Проголосуйте, если есть возможность.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 07:47.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter