Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.10.05;
Скачать: [xml.tar.bz2];

Вниз

Глюк дельфей в консольном приложении   Найти похожие ветки 

 
TStas ©   (2008-08-24 20:07) [0]

i: LongWord;

For i := 2 to High(LongWord) do ....

Дельфи пишут Loop ... no time. Deleted И действительно, цикл не выполнялся. Чтобы заставить его работать, пришлось на While заменить - стало всё нормально. Что это было?


 
Германн ©   (2008-08-24 20:17) [1]

Это твой глюк, а не дельфи. Кто же LongWord использует для переменной цикла?


 
Razrab7 ©   (2008-08-25 11:25) [2]

TStas, так у тебя массив что-ли называется LongWord???
Тогда не удивительно что не работает, это ж зарезервированное слово.


 
Германн ©   (2008-08-25 11:45) [3]


> Razrab7 ©   (25.08.08 11:25) [2]
>
> TStas, так у тебя массив что-ли называется LongWord???

Иногда лучше жевать...


 
Razrab7 ©   (2008-08-25 11:55) [4]

Германн

Возможно ... :) Я просто никогда не писал такой конструкции (от типа данных). Да и зачем вообще это, где реально может пригодиться?


 
Германн ©   (2008-08-25 12:03) [5]


> Razrab7 ©   (25.08.08 11:55) [4]
>
> Германн
>
> Возможно ... :) Я просто никогда не писал такой конструкции
> (от типа данных). Да и зачем вообще это, где реально может
> пригодиться?

Да где угодно может пригодиться. Нужно только понимать, что это означает в разных ситуациях.


 
Ega23 ©   (2008-08-25 12:40) [6]


> Да и зачем вообще это, где реально может пригодиться?


Ага,

type
 TMyType = packed record
   Field1 : Integer;
   Field2 : Integer;
 end;

wrilte (..., SizeOf(TMyType))


Зачем SizeOf(TMyType) писать, когда можно тупо 8?


 
han_malign ©   (2008-08-25 13:10) [7]


> For i := 2 to High(LongWord) do ....

- это действительно "глюк" компилятора оставшийся с древних времен... Компилятор использует знаковое целое при оптмизации for независимо от типа переменной цикла(насчет int64 - не уверен). Только в старых версиях было хуже - такая конструкция приводила к вечному циклу(в D1 - это словили в давние времена - переход переменной цикла на минус и до морковкиного заговения...), без всяких предупрежедний...


 
Anatoly Podgoretsky ©   (2008-08-25 13:22) [8]

> han_malign  (25.08.2008 13:10:07)  [7]

Все нормально документировано, никакого бага нет.

>begin
> counter := initialValue;
>   while counter <= finalValue do
>   begin

Условие counter <= finalValue никогда не выполнится для High(LongWord)
Непонятно зачем нужен цикл на 4 миллиарда иттераций.


 
Ega23 ©   (2008-08-25 13:34) [9]


> Непонятно зачем нужен цикл на 4 миллиарда иттераций.


Моделирование ситуации по методу Монте-Карло?


 
han_malign ©   (2008-08-25 14:18) [10]


> Условие counter <= finalValue никогда не выполнится для High(LongWord)

да ну? Условие - counter > finalValue - не вполнится и при переполнении целого должен получиться вечный цикл... Но на практике уже $80000000 - принимается за отрицательное значение и обламывается компилятором... Хотя в справке четко указано, что это не так...

When counter returns the same value as finalValue, statement is executed once more and the for statement terminates. In other words, statement is executed once for every value in the range from initialValue to finalValue. If initialValue is equal to finalValue, statement is executed exactly once.


вполне, казалось бы, безобидный цикл на две итерации:
var w: longword;
begin
  for w:= $7FFFFFFF to $80000000 do begin
     if(w and $FFFFFF = 0)then Writeln(w);
  end;
end;

[Hint] _for.dpr(): FOR or WHILE loop executes zero times - deleted


 
Anatoly Podgoretsky ©   (2008-08-25 19:22) [11]

LongWord беззнаковое


 
sniknik ©   (2008-08-25 20:00) [12]

> Хотя в справке четко указано, что это не так...
не надо выковыривать изюм из булки... те читать в справке только то что нравиться

смотрим
For statements

counter is a local variable (declared in the block containing the for statement) of ordinal type, without any qualifiers.

т.е. переменная должна быть строго определенного типа

смотрим  дальше

Ordinal types

Ordinal types include integer, character, Boolean, enumerated, and subrange types.


ну, а про то, как типы приводятся один к другому должен знать. если что иши в справке, только читай все подряд, а не только понравившиеся места.


 
sniknik ©   (2008-08-25 20:07) [13]

> [Hint] _for.dpr(): FOR or WHILE loop executes zero times - deleted
цикл выполнится 0 раз - удален.
т.е. выкинуто оптимизатором. попробуй сам привести тип констант, сразу станет ясно почему.


 
TStas ©   (2008-08-25 22:40) [14]

Цикл на 4 миллиарда интераций нужен, чтобы найти все просты да High(LongWord). После чего можно почти мгновенно раскладывать на просты любое число INt64. Только это всё к делу не относится.
High(LongWord) - это я очень правильно написал. Ну не запоминать же значение верхней границы типа. Кроме того, я же не зря именно LOngWord взял. Почему-то тип кардинал имеет диапазон в два раза меньший, т. е. стариший бит в нём из вредности не используют и, видимо, игнорируют.  
> попробуй сам привести тип констант, сразу станет ясно почему.
К чему? чикл со счётчиком типа LOngWord чудестно работает при меньшем диапазоне. Вопрос же не в том, как решить. Решается всё элементарно - заменой for на  While и всё. Вопрос-то почему!
Из ответов понял, что это просто глюк оптимизатора. Глюк злобный, но устранимый.


 
Loginov Dmitry ©   (2008-08-25 22:52) [15]

> Из ответов понял, что это просто глюк оптимизатора. Глюк
> злобный, но устранимый.


Почему глюк? Скорее ограничение. Используй Integer либо while и ничего "глючить" не будет.


 
TStas ©   (2008-08-25 23:01) [16]

Но ведь я хотел не более, чем запусть цикл по диапазону возможных значений переменных. Почему же это ограничение? Если ограничение, то почему его так тщательно скрывают?


 
sniknik ©   (2008-08-25 23:41) [17]

> чикл со счётчиком типа LOngWord чудестно работает при меньшем диапазоне.
самообман... кончится как только вылезет за пределы разрешенного типа к которому LongWord "чудесно" приводиться автоматом. тут то тебя и "накрыло".

> Из ответов понял, что это просто глюк оптимизатора.
форум читаешь также избирательно как han_malign хелп? вот же прямым текстом, и дальше повторялось...
Германн ©   (24.08.08 20:17) [1]
> Это твой глюк, а не дельфи. Кто же LongWord использует для переменной цикла?

> Если ограничение, то почему его так тщательно скрывают?
скрывают только от тех кто читает наперекосяк, или думаешь цитаты в [12] из какогото другого, тайного, хелпа?


 
Loginov Dmitry ©   (2008-08-25 23:47) [18]

> Если ограничение, то почему его так тщательно скрывают?


Правильнее сказать это особенность. Никем она не скрывается. Многие на этом спотыкаются. По неопытности. И я также спотыкался (давно), когда цикл for I := 0 to List.Count-1 приводил к зависанию или AV. Теперь эта "галочка" в виде правила "не использовать в цикле for беззнаковые переменные" просто держится в голове. Подобных мелочей в программисткой практике встречается очень много, и не все они очевидны (а чтоб жизнь медом не казалась).


 
sniknik ©   (2008-08-25 23:49) [19]

> т. е. стариший бит в нём из вредности не используют
ага, тебя позлить...
Anatoly Podgoretsky ©   (25.08.08 19:22) [11]
> LongWord беззнаковое
а интеджер знаковое, но ты не слушай это все из вредности...


 
Германн ©   (2008-08-26 00:02) [20]


> TStas ©   (25.08.08 22:40) [14]
>
> Цикл на 4 миллиарда интераций нужен, чтобы найти все просты
> да High(LongWord).

Ну и сделал бы цикл  
for i:=Low(Integer) to Higj(Integer)
и получил те же 4 миллиарда итераций, но без глюков.


 
Anatoly Podgoretsky ©   (2008-08-26 00:14) [21]


> Почему-то тип кардинал имеет диапазон в два раза меньший,
>  т. е. стариший бит в нём из вредности не используют и,
> видимо, игнорируют.

Ты что в Д2 что ли программируешь?


 
Германн ©   (2008-08-26 01:31) [22]


> Anatoly Podgoretsky ©   (26.08.08 00:14) [21]
>
>

Переход кардинала был, если мне не изменяет мой склероз при смене Д3 на Д4. Но и при этом переходе менялся размер переменной в два раза. А диапазон "кардинала" продолжал соответствовать диапазону Integer.


 
Германн ©   (2008-08-26 01:41) [23]


> Германн ©   (26.08.08 01:31) [22]

Не.
Наверно всё-таки я не совсем прав.
Давно это было. Мох истории заслоняет глаза. :(


 
Anatoly Podgoretsky ©   (2008-08-26 08:54) [24]

> Германн  (26.08.2008 1:31:22)  [22]

Склероз - у Борланда одно время cardinal был 31 бит, потом стал 32, при этом многократно менялся исходный тип. Весь мир очень долго на ними смеялся, это же надо придумать cardinal в 31 бит, единственно, что их оправдывает, так это изменяемые константы!!!


 
han_malign ©   (2008-08-26 10:29) [25]


> только читай все подряд, а не только понравившиеся места.

читаю все подряд:
Integer types
Fundamental integer types include Shortint, Smallint, Longint, Int64, Byte, Word, and Longword.

И если Longword - не перечислимый - то просветите меня темного - какой же?


 
han_malign ©   (2008-08-26 10:39) [26]


> Ну и сделал бы цикл  
> for i:=Low(Integer) to Higj(Integer)
> и получил те же 4 миллиарда итераций, но без глюков.

угу, то есть цикл
    for w:= $8000000 to $7FFFFFFF do ...;//причем без всяки ошибок w:LongWord
- это нормально, а
    for w:= $0000000 to $FFFFFFFF do ...;
- это глюк программиста...

Все-таки, это недокументированная особенность(назовем это так) компилятора...


 
sniknik ©   (2008-08-26 11:06) [27]

> читаю все подряд:
> Integer types
мало того, что выборочно читаешь так еще и выдумываешь. не было там указаний на целочисленные типы только на порядковые и перечислено какие именно т.е. integer, ... т.д. (было уже)
как ты из одного типа integer получил целый класс Integer types, это вопрос, и вопрос этот не ко мне.

> Все-таки, это недокументированная особенность(назовем это так) компилятора...
ну, если ламеризм это особенность, а компилятор это тот запускает процесс компилирования... согласен, так уж и быть.

скажи как бы вот ты привел константу заданную в 16-чном представлении к нормальному виду? как определил бы знак, при полной неопределенности к какому типу приводить? например $FF это 255 без знака или -1 со знаком? это если размерность типа 1 байт а если и это неопределено?
вот как бы ты сделал?
в дельфи сделано очень правильно, для приведения используется тип integer, все четно, никаких неопределенностей, как задокументировано так и делается. а до чтения мыслей, что именно ты имеешь в виду под константой если когда компьютеры и дойдут,... программисты к тому времени будут не нужны.
а пока, то что пишешь то и получаешь, а не то что хотел.

> угу, то есть цикл
>     for w:= $8000000 to $7FFFFFFF do ...;//причем без всяки ошибок w:LongWord
> - это нормально, а
>   for w:= $0000000 to $FFFFFFFF do ...;
на варнинги внимания не обращаешь?
> - это глюк программиста...
т.е. привести тип руками так и не удосужился так понимаю? молодец, так держать! больше ламеров - меньше конкурентов.


 
han_malign ©   (2008-08-26 11:18) [28]


> при полной неопределенности к какому типу приводить?

- угу, а тип итератора цикла интересен только Пушкину..


> в дельфи сделано очень правильно, для приведения используется
> тип integer, все четно, никаких неопределенностей

for w:= $8000000 to $7FFFFFFF do ...;
@@loop
...
inc ebx
cmp ebx, $80000000
jnz @loop

покажите мне тут знаковую оперцию, Гуру(три раза ку)...


 
Anatoly Podgoretsky ©   (2008-08-26 12:04) [29]

> han_malign  (26.08.2008 11:18:28)  [28]

Проверка на равенство в с константой не может быть знаковым или беззнаковым, оно одно JNE/JNZ
Кроме того сгенерированый текст зависит от версии Виндоус, у меня например другой код

test ebx, ebx
jnz ...


 
Anatoly Podgoretsky ©   (2008-08-26 12:12) [30]

> han_malign  (26.08.2008 11:18:28)  [28]

Если заменить индексы переменными, то код будет сгенерирован другой, будет например два счетчика.
Я запускал, работает только дождаться конечно не могу, слишком большой цикл


procedure TForm2.Button1Click(Sender: TObject);
var
  I: LongWord;
  a,b: LongWord;
begin
  a:= 2;
  b:= High(LongWord);
  for I := a to b do begin
    Label1.Caption := IntToStr(I);
    Application.ProcessMessages;
  end;
end;


inc esi
dec ebx
jnz loop


 
sniknik ©   (2008-08-26 12:37) [31]

> покажите мне тут знаковую оперцию, Гуру(три раза ку)...
интересное такое кино... а с какой радости дельфи использовать знаковую операцию если сравнение на 0 оптимальнее. и создание оптимального кода это как раз то к чему следует стремиться.
кстати насколько помню код точно различается в зависимости от того используется переменная цикла в цикле или нет.  

тем более результирующий код не документирован (обязателен быть именно таким), а типы к использованию в for документированы. вот на этом все, алес, конец абсурду.


 
han_malign ©   (2008-08-26 17:06) [32]


> а типы к использованию в for документированы. вот на этом все, алес, конец абсурду.

- угу, и Longword в них входит...
Когда вы мне объясните почему Longword не является ordinal(что противоречит статье Delphi Help->Ordinal types), или укажете статью Delphi Help в которой указано, что итератором цикла может быть только знаковое целое - вот тогда я посыплю голову пеплом...

DIXI


 
han_malign ©   (2008-08-26 17:18) [33]


> Если заменить индексы переменными, то код будет сгенерирован
> другой, будет например два счетчика.
> Я запускал, работает только дождаться конечно не могу, слишком
> большой цикл


program _for;
{$APPTYPE CONSOLE}
uses Windows;
var dw, h: longword;
   w: word;
begin
  h:= $FFFFFFFF;
  for dw:= 0 to h do begin
     if(dw and $FFFFFF = $FFFFFF)then Writeln(dw);
  end;

  for w:= 0 to h do begin
     if(w and $FFF = $FFF)then Writeln(w);
  end;
end.

- 10 секунд...
которые четко показывают, что цикл FOR может правильно работать с Longword, а случай с константами все-таки глюк...


 
sniknik ©   (2008-08-26 20:41) [34]

> или укажете статью Delphi Help в которой указано
вообщето я с этого начал...
sniknik ©   (25.08.08 20:00) [12]
> смотрим
> For statements
> counter is a local variable (declared in the block containing the for statement) of ordinal type, without any qualifiers.
> т.е. переменная должна быть строго определенного типа
> смотрим  дальше
> Ordinal types
> Ordinal types include integer, character, Boolean, enumerated, and subrange types.
выделенное и есть топики/разделы хелпа

> что цикл FOR может правильно работать с Longword
частный случай, видать изза того, что сравнение с переменной в цикле иначе реализовано чем с константой. (асм смотрел? проверь)
но не переписывать же изза одного случая весь хелп... %), будет не хелп, а "здесь играем, здесь не играем а здесь рыбу заворачивали".
хотя честно, вот этого я не знал... всегда на хелп полагался.


 
TStas ©   (2008-08-26 20:50) [35]

> Anatoly Podgoretsky Нет. Это написано у Фаронова. Дельфи у меня седьмые.


 
TStas ©   (2008-08-26 20:59) [36]

> LongWord беззнаковое
а интеджер знаковое, но ты не слушай это все из вредности...
У Фаронова написано, что у типа Cardinal 0 - 2 147 483 467, именно поэтому я и удивился: это ведь 4-х битный беззнаковый тип. У Integer, в старшем бите знак, а диапазон верхний тот же. Вот и выходит, что почему-то самый старший бит просто игнорируется.
А с LongWord всё нормально. Может, это просто у Фаронова опечатка?
Я как-то раньше не пользовался типом LongWord, мне, ошибочно казалось, что это просто псевдоним сишного DWORD.
Но если у Фаронова не опечатка, получается, что Cardinal просто Abs(Integer).
Век живи, век учись, дураком помрёшь!


 
sniknik ©   (2008-08-26 21:20) [37]

получается, что Cardinal
хелп
Integer types
Cardinal 0..4294967295 unsigned 32-bi

Longword 0..4294967295 unsigned 32-bit


недоразумения изза того что при переводе из 16го представления совершенно невозможно определить со знаком оно или нет, тип в представление не закладывается.


 
TStas ©   (2008-08-26 21:32) [38]

>тип в представление не закладывается.
На самом деле, вся математика с каким либо типом - это математика в конечном кольце с модулем High(TypeName). Естественно, что в этом случая знак просто понимается. То есть у числа -1 для ShrtInt знак есть, а у 65535 типа Ворд знака нет, хотя это одно и то же число.
Ведь как считается  - (Число)? Берём само число, инвертируем биты нотом. Получится число, которое при сложении с ихсодным и даст High(TypeName), ведь во всех битах суммы будут единицы. Если теперь прибавить 1, то получим число, у которго старший бит и 1, а остальные биты - нули, но 1 отрежется из-за переполнения диапазона и получится 0. Но это тоже самое, что проводить операции с беззнаковыми числами по модулю 2^(8*Размер). Просто кому как нравится себе это представлять.


 
sniknik ©   (2008-08-26 21:48) [39]

> Просто кому как нравится себе это представлять.
нравится не нравится... несерьезно. вопрос что делать дельфе , причем однозначно.
я уже предлагал ручками перевести и подставить, могу и тебе предложить... типа я программист, а ты компилятор...
итак задаю
$FF -
$FFFF -
$FFFFFFFF -
$80 -
$8000 -
$80000000 -
какие цифры написаны?

кстати а почему только цифры? тут както обсуждение про цвет были..., я тут мог и массив RGB задать...


 
Anatoly Podgoretsky ©   (2008-08-27 00:35) [40]

> sniknik  (26.08.2008 20:41:34)  [34]

> частный случай, видать изза того, что сравнение с переменной в цикле иначе реализовано чем с константой. (асм смотрел? проверь)
> но не переписывать же изза одного случая весь хелп... %), будет не хелп, а "здесь играем, здесь не играем а здесь рыбу заворачивали".
> хотя честно, вот этого я не знал... всегда на хелп полагался.

Я привел три варианта сгенерированого кода, различие большое. Знание значения на этапе компиляции (константы), позволяет сделать другой, более оптимальный код, приводя это к Integer, но это же не позволяет работать на границах или обеспечить должную последовательность.

На самом деле зачем гадать, как это будет для разных услоивий или версий Дельфи, когда есть WHILE и расширеные типы данных, например Int64, которые позволяют сделать надежный и управляемый код.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2008.10.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.007 c
2-1219739361
max
2008-08-26 12:29
2008.10.05
String literals may have at most 255 elements


15-1219047498
vajo
2008-08-18 12:18
2008.10.05
Можно апгрейдить Vista Business до 2008 Server?


15-1218610196
MsGuns
2008-08-13 10:49
2008.10.05
Лето или очередная летаргия форума ?


9-1171785599
Sonio
2007-02-18 10:59
2008.10.05
Будущий геймдев!


15-1218565213
igm
2008-08-12 22:20
2008.10.05
Требуется программист для разовой работы.





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