Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


Страницы:   1 2 3

TStas ©   (2008-08-24 20:07:00) 

i: LongWord;

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

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


DiamondShark   (2008-08-27 17:43:00) [1]


> types сдесь относится к subrange, ни к чему больше, проконсультируйся
> со спецом по грамматике английского языка

Угу. А к enumerated, надо полагать, не относится.
И что, тогда, такое character? Что такое character types, знаю -- это char и widechar, а слова character в Паскале нету.


> повторю, результирующий код не документирован, и может быть
> любым!

Речь идёт не о результирующем коде, а о семантике оператора.
В рассматриваемом случае кода вообще нет, потому что компилятор сравнил константы как знаковые 32-битные, на что права не имел.

Это именно глюк компилятора.


han_malign   (2008-08-27 16:28:00) [2]


> заход на очередной круг? по справке он там не может иметь тип Longword

кокретно - место в справке где это написано...
кокретно - где написано, что Longword не перечислимый тип...

> повторю, результирующий код не документирован, и может быть любым!

конкретно - пример - где результирующий код не соответсвует приведенной схеме, хотя бы из тех "3-х (или 4х?) приведенных вариантов"...

"так держать! больше ламеров - меньше конкурентов."(c)sniknik


sniknik   (2008-08-27 14:06:00) [3]

>> Ordinal types
>> Ordinal types include integer, character, Boolean, enumerated,  and subrange types.
ну теперь понятно откуда взял... говорю же, читаешь выборочно. взял и составил чего хочется из слов и неважно что к чему относится. (types сдесь относится к subrange, ни к чему больше, проконсультируйся со спецом по грамматике английского языка)

> - так, все-таки, Longword, Word, Byte, a также Int64, ShortInt и SmallInt - ordinal types, и если нет - то какие?
а проверь, и подставь в цикл переменную типа Int64 (единственное автоматом не приведется т.к. размером не вышла).

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

> Для тех кто в танке:
и смысл подобного приведения, если компилятор будет проверять по такому (автоматическое приведение, сколько уже повторялось)
for dw:= integer(LongWord(0)) to integer(LongWord($FFFFFFFF)) do
?

> - в Pascal цикл For всегда имеет одинаковую реализацию:
и это после 3-х (или 4х?) приведенных вариантов?...
повторю, результирующий код не документирован, и может быть любым! (вот в твоем примере с переменной повезло и выдало такую проверку которая при неверном значении верно сработала. но это не обязаловка раз в хелпе не прописано)

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


han_malign   (2008-08-27 10:49:00) [4]


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

- так, все-таки, Longword, Word, Byte, a также Int64, ShortInt и SmallInt - ordinal types, и если нет - то какие?


> $80000000 -
> какие цифры написаны?
> ... я тут мог и массив RGB задать...

- вообще-то, Pascal - язык высокого уровня, со строгой типизацией данных...
в вашем примере, написаны шестнадцатеричные числа в мнемонике Pascal.
В конкретном контейнере(например итераторе цикла For) - такие данные имеют кокретный смысл...
Например, если итератор цикла For имеет тип Longword - то это соответственно
255
65535
4294967295
256
65536
2147483648
--------------------
For statements:
- initialValueand finalValueare expressions that are assignment-compatible with counter.

Для тех кто в танке:
for dw:= LongWord(0)to LongWord($FFFFFFFF)do
[Hint] _for.dpr(): FOR or WHILE loop executes zero times - deleted


> частный случай, видать изза того, что сравнение с переменной в цикле иначе реализовано чем с константой

- в Pascal цикл For всегда имеет одинаковую реализацию:
1. Проверка условия входа в цикл
2. Инициализация итератора, счетчика и терминирующего значенияцикла.
3. Тело цикла.
4. Изменение итератора и счетчикацикла.
5. Сравнение счетчика с терминирующим значением.
   Если не совпадает - переход на 3.

В зависимости от оптимизации:
- проверка условия входа в цикл(1.) может быть выкинута на этапе компиляции.
- итератор может выполнять функцию счетчика(чаще всего).
- терминирующее значение может быть задано констатой.
- сравнение(5.) может быть опущено при явной проверке результата изменения счетчика(в Delphi выход из цикла происходит только при взведенном флаге Z - без всяких знаков)

Вот, как раз - проверка условия входа в цикл(1.) - в анализаторе компилятора, и в скомпилированном коде - имеет разную реализацию, что и является глюком...


Германн   (2008-08-27 01:09:00) [5]

Вот кстати тоже о типах.
http://dev2.delphimaster.ru/forum/other/1178872210


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

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

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

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

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


sniknik   (2008-08-26 21:48:00) [7]

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

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


TStas   (2008-08-26 21:32:00) [8]

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


sniknik   (2008-08-26 21:20:00) [9]

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

Longword 0..4294967295 unsigned 32-bit


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


TStas   (2008-08-26 20:59:00) [10]

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


TStas   (2008-08-26 20:50:00) [11]

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


sniknik   (2008-08-26 20:41:00) [12]

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


han_malign   (2008-08-26 17:18:00) [13]


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


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, а случай с константами все-таки глюк...


han_malign   (2008-08-26 17:06:00) [14]


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

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

DIXI


sniknik   (2008-08-26 12:37:00) [15]

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

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


Anatoly Podgoretsky   (2008-08-26 12:12:00) [16]

> 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


Anatoly Podgoretsky   (2008-08-26 12:04:00) [17]

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

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

test ebx, ebx
jnz ...


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


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

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


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

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

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


sniknik   (2008-08-26 11:06:00) [19]

> читаю все подряд:
> 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 10:39:00) [20]


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

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

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


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо