Форум: "Основная";
Текущий архив: 2006.09.10;
Скачать: [xml.tar.bz2];
ВнизЦикл for, так нелюбимый компилятором Найти похожие ветки
← →
TUser © (2006-07-26 12:18) [0]
procedure TForm1.Button1Click(Sender: TObject);
var i: longword;
begin
for i := 0 to high (longword) do
Label1.Caption := inttostr(i);
end;
пишет, что мол
[Hint] Unit1.pas(30): FOR or WHILE loop executes zero times - deleted
С чего вдруг zero times??
← →
ЮЮ © (2006-07-26 12:22) [1]Потому что достаточно
Label1.Caption := inttostr( high (longword));
Сколько цикл ни крути результат один и тот же. Даже компилятор видит :)
← →
begin...end © (2006-07-26 12:23) [2]> TUser © (26.07.06 12:18) [0]
> FOR or WHILE loop executes zero times - deleted
You may see this warning if a FOR loop increments its control variable from a value within the range of Longint to a value outside the range of Longint. For example:
var I: Cardinal;
begin
For I := 0 to $FFFFFFFF do
...
This results from a limitation in the compiler which you can work around by replacing the FOR loop with a WHILE loop.
(с) Delphi Help
← →
begin...end © (2006-07-26 12:30) [3]> ЮЮ © (26.07.06 12:22) [1]
Нет, причина не в этом. Присвоение значения переменной и запись в свойство -- разные вещи. В первом случае оптимизатор мог оставить от цикла одну итерацию, потому что конечный результат действительно был бы заранее известен. В случае же изменения значения свойства результат вполне мог бы зависеть от числа обращений к нему.
← →
Ketmar © (2006-07-26 13:41) [4]насколько я помню -- из-за того, что границы у for проверяются как числа со знаком. а High(LongWord) -- это -1, которое меньше нуля. вот цикл и застрелили. %-)
← →
TUser © (2006-07-26 14:28) [5]> High(LongWord) -- это -1
Это не так, там четыре на десять в какой-то.
> begin...end © (26.07.06 12:23) [2]
Спасибо
← →
default © (2006-07-26 14:45) [6]цикл срывается примерно начиная с середины LongWord(точно не считал)
то есть типа компиллер смотрит на LongWord как на число со знаком
пофиксить можно так
procedure TForm1.Button1Click(Sender: TObject);
var i, max: longword;
begin
max := High(LongWord);
for i := 0 to max do
Label1.Caption := inttostr(i);
end;
← →
Ketmar © (2006-07-26 14:47) [7]>TUser © (26.07.06 14:28) [5]
это так. $FFFFFFFF (максимальное значение LongWord) -- это -1 для Integer.
← →
default © (2006-07-26 14:58) [8]"цикл срывается примерно начиная с середины LongWord"
под этим я понимаю - если правая граница цикла более примерно середины LongWord(точно не измерял, но по всей вероятности так оно и есть) цикл не выполняется ни разу
← →
TUser © (2006-07-26 15:05) [9]
> >TUser © (26.07.06 14:28) [5]
> это так. $FFFFFFFF (максимальное значение LongWord) -- это
> -1 для Integer.
При чем тут integer?
← →
default © (2006-07-26 15:09) [10]TUser © (26.07.06 15:05) [9]
поняли в чём дело-то было?
компиллер смотрит на LongWord как на число со знаком
поэтому для отрицательных чисел(как он думает) цикл и не выполняется(правая граница цикла меньше левой)
чтобы ещё больше в этом убедить достаточно написать
procedure TForm1.Button1Click(Sender: TObject);
var i: longword;
begin
for i := high(longword) to high (longword) do
Label1.Caption := inttostr(i);
end;
то есть для компиллера это цикл в границах -1..-1
цикл выполнится один раз
это же всё требует элементарной сообразительности...
← →
DrPass © (2006-07-26 15:10) [11]
> TUser © (26.07.06 15:05) [9]
Потому что компилятор неявно приводит число к типу integer. И получается, что у тебя цикл от 0 до -1
← →
default © (2006-07-26 15:16) [12]DrPass © (26.07.06 15:10) [11]
интересно с какой версии и по какую эта ошибка компилятора присутствует
← →
Мефисто (2006-07-26 15:43) [13]
> for i := high(longword) to high (longword) do
А почему первым не Low?
← →
tesseract © (2006-07-26 15:50) [14]
> default © (26.07.06 15:16) [12]
С первой по последнюю и это не ошибка.
← →
TUser © (2006-07-26 15:54) [15]Понял - high(longword) для конмпилятора означает константу типа longint.
← →
default © (2006-07-26 16:02) [16]Мефисто (26.07.06 15:43) [13]
чтобы понять, что не всему виной правая граница High(LongWord)
то есть цикл можно запустить меняя левую границу
tesseract © (26.07.06 15:50) [14]
это написано в справке?
не ошибка?
хорошо, почему тогда когда счётчик цикла имеет тип Byte строка
for i := 0 to High(Byte) do ; будем выполняться заявленное число раз
почему, проводя аналогию, компиллер не смотрит на счётчик цикла как на переменную типа ShortInt?
← →
default © (2006-07-26 16:09) [17]DrPass © (26.07.06 15:10) [11]
если бы он приводил к Integer, то цикл бы не начинал выполняться при правой границе равной половине Integer, а не LongWord
опыт+логика=решение проблемы
← →
tesseract © (2006-07-26 16:12) [18]
> почему, проводя аналогию, компиллер не смотрит на счётчик
> цикла как на переменную типа ShortInt?
размер Byte и LongWord?
← →
default © (2006-07-26 16:20) [19]tesseract © (26.07.06 16:12) [18]
я провожу аналогию
LongWord и LongInt - оба по четыре байта, одно трактуется на число без знака, другое со знаком
Byte и ShortInt - оба по одному байту, одно трактуется на число без знака, другое со знаком
эксперимнт показывает, что компиллер в аналогичных ситуациях ведёт себя по-разному
то есть Вы и сейчас станете говорить, что ошибки нет ни в каком из этих случаях? а если компилятор компилировал бы код как захочет это тоже было бы неошибкой?
← →
tesseract © (2006-07-26 16:25) [20]
> эксперимнт показывает, что компиллер в аналогичных ситуациях
> ведёт себя по-разномуто есть Вы и сейчас станете говорить,
> что ошибки нет ни в каком из этих случаях? а если компилятор
> компилировал бы код как захочет это тоже было бы неошибкой?
>
Вспоминаем про четырёхбайтовое выравнивание, и то что все целые числа переводяться компилятором в 32-битные для повышения скорости кода.
байт всё равно будет cardinal. И твой цикл до минусовых значений просто не дойдёт.
ЗЫ: цикл с longWord и 64-битными регистрами должен работать нормально.
← →
default © (2006-07-26 16:28) [21]tesseract © (26.07.06 16:25) [20]
мне как, пользователю, компилятора плевать как реализованы его внутренности
мне важна лишь логика
я заявил переменную цикла как LongWord
правую границу установил в пределах LongWord и по смыслу трактовки чисел типа LongWord(то есть как беззнаковых)
ВСЁ! МЕНЯ БОЛЬШЕ НИЧЕГО НЕ ДОЛЖНО ВОЛНОВАТЬ!!!
← →
tesseract © (2006-07-26 16:30) [22]
> default © (26.07.06 16:28) [21]
+5
Срочно за учебником по теории чисел.
и Основы цифровой схемотехники тоже можно подучить.
ЗЫ : Сорри за флуд
← →
default © (2006-07-26 16:33) [23]tesseract © (26.07.06 16:30) [22]
оставлю это без комментариев(да и что тут комментировать?:))
пусть каждый делает для себя выводы самостоятельно
← →
default © (2006-07-26 16:44) [24]tesseract © (26.07.06 16:30) [22]
ради смеха скажите почему тогда работает
procedure TForm1.Button1Click(Sender: TObject);
var i, max: longword;
begin
max := High(LongWord);
for i := 0 to max do
Label1.Caption := inttostr(i);
end;
← →
default © (2006-07-26 16:47) [25]tesseract © (26.07.06 16:30) [22]
а лучше поясните в чём ЛОГИЧЕСКИ неправ пользователь компилятора в каком-то из этих случаях
в сабже и здесь
то есть основания пользователя какие должны быть чтобы он, использовал переменную в правой границе цикла? определения типа счётчика мало?
может быть всё-таки признаем - что компилятор в данном случае неправ
← →
tesseract © (2006-07-26 16:48) [26]явное указание компилятору работать с целым беззнаковым числом.
← →
default © (2006-07-26 16:50) [27]tesseract © (26.07.06 16:48) [26]
это, как говорят студенты, и козе понятно
ладно, хотите веровать в правоту компилятора - флаг в руки
оправдывайте его всякой мурой
← →
tesseract © (2006-07-26 16:53) [28]
> default © (26.07.06 16:50) [27]
Вот так всегда, хочешь человеку помочь, а он оказывается юзером......
← →
default © (2006-07-26 16:59) [29]tesseract © (26.07.06 16:53) [28]
я не понял Вашей позиции
какие-то невнятные ссылки на особенности реализации работы компилятора
можно точно сформулировать? очень интересно
а то такое ощущение, что Вы просто констатируете действия компилятора и на каждое такое действие говорите "Правильно. Ай да маладец!. Ай да умница!"
← →
tesseract © (2006-07-26 17:15) [30]
> default © (26.07.06 16:59) [29]
Да нет я просто говорил про особенности работы процессора.
ссылки по этому вопросу.
← →
default © (2006-07-26 17:21) [31]"явное указание компилятору работать с целым беззнаковым числом." (1)
и это смешно
procedure TForm1.Button1Click(Sender: TObject);
var i: longword;
begin
for i := 0 to LongWord($FFFFFFFF) do
Label1.Caption := inttostr(i);
end;
это также не работает, хотя тут есть (1)
так кто дурак? компилятор или мы?
← →
tesseract © (2006-07-26 17:37) [32]Это такая особенность компилятора.
Он смотрит на границы цикла, и видит, что у тебя правая граница -1, а левая - 0 . Т.е цикл не нужно выполнять.
default © (26.07.06 16:44) [24]
Ты в цикле используешь переменную, т.е. не константу -1, компилятор НЕ РАССЧИТЫВАЕТ значение границ цикла во время компиляции.
приведение будет выполняться позже - в рантайм.
Хочешь от этого избавиться - выключи оптимизацию в настройках проекта.
← →
begin...end © (2006-07-26 17:40) [33]> default © (26.07.06 16:02) [16]
> это написано в справке?
Это написано в справке.
← →
default © (2006-07-26 17:48) [34]begin...end © (26.07.06 17:40) [33]
я уже видел, поздновато правда
"This results from a limitation in the compiler which you can work around by replacing the FOR loop with a WHILE loop."
можно расшифровать?
tesseract © (26.07.06 17:37) [32]
от чего этого? с выключенной всё-равно не работает
← →
tesseract © (2006-07-26 17:48) [35]
> от чего этого? с выключенной всё-равно не работает
У меня работает.
← →
begin...end © (2006-07-26 17:50) [36]> default © (26.07.06 17:48) [34]
Так, вроде бы, и не зашифровано ничего :)
"Это следствие ограничения компилятора, которое можно обойти, заменив цикл FOR на WHILE".
← →
default © (2006-07-26 17:52) [37]tesseract © (26.07.06 17:37) [32]
блин про другой пост подумал.....
если отключить, [24] работает
← →
default © (2006-07-26 17:54) [38]begin...end © (26.07.06 17:50) [36]
хорошо, в справке есть, только вот убого это всё-равно...логика кривая, каждый раз на while, вводить переменную для for, ...всё это как-то...не очень
← →
default © (2006-07-26 17:59) [39]почему бы компиляру, например, автоматически не вставлять код для переменной цикла в правой части for и избавить пользователя от подобной галиматьи, по-другому не назовёшь
← →
begin...end © (2006-07-26 18:13) [40]> default © (26.07.06 17:54) [38]
Так я ж и не спорю, что логика кривая. Кривая. Но документированная :)
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2006.09.10;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.037 c