Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.10;
Скачать: CL | DM;

Вниз

Цикл 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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.028 c
15-1155554018
ArtemESC
2006-08-14 15:13
2006.09.10
государство Монако!!!


15-1155873787
kolyann..
2006-08-18 08:03
2006.09.10
?!


2-1156168479
Handle
2006-08-21 17:54
2006.09.10
Про файлы


15-1155587414
lookin
2006-08-15 00:30
2006.09.10
Сны


4-1147245127
Elen
2006-05-10 11:12
2006.09.10
Перехват поступления данных из COM порта