Форум: "Основная";
Текущий архив: 2004.02.06;
Скачать: [xml.tar.bz2];
ВнизЗависание одной строчки кода при переполнении. Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.033 c