Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.074 c
2-1156140048
barakuda
2006-08-21 10:00
2006.09.10
Сложная выборка


2-1156268259
ffo
2006-08-22 21:37
2006.09.10
(API) Не могу текст переместить в нужное место на форме


4-1147767225
aleks_z
2006-05-16 12:13
2006.09.10
SetupApi


2-1156222737
qqpp
2006-08-22 08:58
2006.09.10
Как узнать количество каталогов


15-1155639110
Rouse_
2006-08-15 14:51
2006.09.10
Хех, народ хочет сделать Дельфи опенсорсным проектом :)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский