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

Вниз

Зависание одной строчки кода при переполнении.   Найти похожие ветки 

 
Erik ©   (2004-01-22 11:06) [0]

TDecNo = packed record
HiByte: Byte;
LoWord: Word;
end;
..............
function IntToDecNo(I: Integer): TDecNo;
begin
Result.HiByte := (I and $FF0000); // - зависает здесь.
Result.LoWord := System.Swap(I and $FFFF);
end;
Я конечно понимаю почему происходит ошибка, но почему все отанавливается неясно. Заодно у кого есть желание могут посоветовать как это лучше написать.


 
snake1977   (2004-01-22 11:32) [1]

завичает потому как лезет не в ту память, а скорее всего записывает в стек , там где у тебя адрес возврата находится

сделай так

TDecNo = packed record
HiByte: Byte;
LoWord: Word;
end;
..............
function IntToDecNo(I: Integer): TDecNo;
type TFull=record
case t:Boolean of
true: (loWord:Word; LoByte,HiByte:Byte);
false: (Full:Integer);
end;
Var t:TFull;
begin
t.Full:=i;
Result.HiByte := t.LoByte;
Result.LoWord := t.LoWord;
end;


 
jack128 ©   (2004-01-22 11:42) [2]

не знаю, у меня ничего не зависает..

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

Это где там не в ту память лезут? При присваивании, чтоли? Нечего криминального в коде нету, за исключением, что HiByte всегда - 0.


 
Erik ©   (2004-01-22 11:45) [3]

Вобщето I всегда имеет тип Integer, но недолжно превышать
65535(FFFF). Я думаю лучше делать raise.


 
AKul ©   (2004-01-22 12:08) [4]

Причем здесь переполнение????
Даже если написать так:
Result.HiByte := I; // I - integer, HiByte - Byte
то компилятор создаст код, который в HiByte будет записывать все равно только младший байт I.
В теле процедуры IntToDecNo (все AND в которой можно поубирать) ошибки нет.
Она может возникать только если Result расположено в "неправильном" месте.
У тебя есть что-то типа
NewValue:=IntToDecNo(Value);
Так вот, что у тебя NewValue, где она расположена? Проверь.
Ошибка, скорее всего, в этом (другой я здесь не вижу!).


 
Ihor Osov'yak ©   (2004-01-22 12:27) [5]

хм...
2 Erik © (22.01.04 11:06)

> но почему все отанавливается неясно
Во первых, что такое "отанавливается"?
Во вторых - при выполнении
Result.HiByte := (I and $FF0000); // - зависает здесь.
если I >= $10000 или для любого отрицательного произойдет искл. ситуация, сообщение о которой Вы, наверно, как то умудрились не заметить - и, наверное, отсюда выводы якобы о зависании.. Если Вы все же делаете обработку искл. ситуаций - то, сообщения может и не быть - это зависит от многих факторов - но и "зависания" наблюдатся. Хотя, имхо, если Вы умудряетесь писать подобный код - я немного сомневаюсь, что вы обрабатываете исключения.

> как это лучше написать

Расскажите, что вам нужно, то может и посоветует, кто-нибуть, как это оптимальнее сделать..

2 [1] snake1977 (22.01.04 11:32)
Код от Erik никаких проблем для стека не создает и никуда не "лезет"


2 [3] Erik © (22.01.04 11:45)

> но недолжно превышать
65535(FFFF). Это было верно для паскаля и первого делфи.


 
AKul ©   (2004-01-22 12:34) [6]


> Ihor Osov"yak © (22.01.04 12:27) [5]


> если I >= $10000 или для любого отрицательного произойдет
> искл. ситуация

Это только в том случае если у него включен ключ R ({$R+}).
В противном случае ни о каком исключении речи быть не может - тип с большим размером "обрежется" до меньшего и все будет нормально!


 
AKul ©   (2004-01-22 12:46) [7]


> Erik © (22.01.04 11:06)
> Result.HiByte := (I and $FF0000);


Да, еще, что с AND, что без него все равно в HiByte будет 0.
Вместо
I and $FF0000
нужно использовать
I shr 16
ставить AND $FF после этого выражения вовсе не обязательно, а что бы все выглядело правильно (да и ктому же, что бы не вызывалось исключение при включенном ключе R) лучше написать:

Result.HiByte := Byte(I shr 16);


 
Ihor Osov'yak ©   (2004-01-22 13:18) [8]

2 [6] AKul © (22.01.04 12:34)

> Это только в том случае если у него включен ключ R ({$R+}).

В любом нормальном букварике советую этот ключ включать во время отладки.
Зы. Я пытался предствить причину, из-за которой человек делал вывод, что у него якобы
Result.HiByte := (I and $FF0000); // - зависает здесь.

версия о проморганном сообщении об эксепшен (естественно, при {$R+}) мне показалась наиболее вероятной.

И вообще, ловить ошибку в 17 строке на расстоянии - очень неблагодарное занятие..

Зы - вчера своей дочурке азы программирования обьяснял, позвала - не могла разобраться с какой-то ошибкой.. Я смотрел минут пять - не мог сообразить, как такую ошибку вызвать.. Посмотрел по коду. Я даже не думал, что такое можно написать..
зы2 - но девчонка быстро соображает - надеюсь эта стадия у нее быстро пройдет..


 
AKul ©   (2004-01-22 14:40) [9]


> Ihor Osov"yak © (22.01.04 13:18) [8]


> Зы. Я пытался предствить причину, из-за которой человек
> делал вывод, что у него якобы
> Result.HiByte := (I and $FF0000); // - зависает здесь.
>
> версия о проморганном сообщении об эксепшен (естественно,
> при {$R+}) мне показалась наиболее вероятной.


У меня при просмотре возникло 2 варианта:
1. Result (это фактически указатель на то место, куда будет возвращен результат) указывает не туда куда надо (Присваивание результата функции ведется в "неправильную" область).
2. Сработала проверка диапазона, но первоначально я ее отклонил по той причине, что автор вопроса сказал в [3], что I у него не превышает 65535 (может от незнания типа Integer?),а в таком случае I and $FF0000 всегда будет равно 0 (смысла делать AND над отрицательным число, предварительно не подготовив его я не увидел). Да и ключ R по умолчанию то выключен (и автор об этом ничего не упоминал).

Да и судя по всему, он в букварике только картинки смотрел ;-).


> Erik © (22.01.04 11:06)

Если бы Вы правильно сформулировали ошибку, возникающую при "останаваливании" (как Вы говорите) программы, то Вам бы давно уже дали точный ответ на Ваш вопрос!


 
Ihor Osov'yak ©   (2004-01-22 15:04) [10]

> 1. Result (это фактически указатель на то место, куда будет возвращен результат) указывает не туда куда надо

Ну, это еще постараться нужно. А приведенный выше код (если он приведен точно) такого старания не демонстрирует.

Ладно, развели хвилосовствование на пустом месте.



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

Текущий архив: 2004.02.06;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.019 c
1-16331
oleg_SYS
2004-01-24 21:27
2004.02.06
Где находятся в реестре пункты контекстных меню?


1-16395
buka
2004-01-21 19:51
2004.02.06
Вопрос к тому кто занимался с Wise Installer


1-16264
MakNik
2004-01-26 09:58
2004.02.06
TEDIT


1-16466
KLAUS
2004-01-27 20:41
2004.02.06
ImagaBase


1-16348
AlexLine
2004-01-24 13:58
2004.02.06
SpeedButton