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

Вниз

Project/Options/Compiler/ RANGE CHECKING   Найти похожие ветки 

 
DevilDevil ©   (2007-02-02 13:21) [0]

Довольно долго мучился переделывал одну библиотеку, довёл до нужного мне состояния; всё работало великолепно. Переношу полученную библиотеку в новый проект, запускаю, - RunTime Error 216 (это ошибка доступа к памяти). Долго мучился, перекидывал проект из папки в папку, менял опции компилятора.... то работает, то НЕТ. В конце концов пришёл к выводу, что ошибки возникают если ставить в опциях компилятора флажок "Range Checking", если убирать, то всё нормально работает. Так вот собственно вопросы:

1) что из себя представляет эта опция компилятора
2) из-за чего чаще всего возникают такие ошибки
3) какие подводные камни могут мне встретиться при поиске места ошибки
4) пару советов, как обнаружить ошибку с "наименьшими потерями". Дело в том, что там очень много кода; преимущественно на ассмбелере.

Заранее Спасибо!


 
Anatoly Podgoretsky ©   (2007-02-02 13:29) [1]

> DevilDevil  (02.02.2007 13:21:00)  [0]

Ошибка диапазона и правильно работает - не верю.


 
TRUNK ©   (2007-02-02 14:14) [2]

ERangeError возникает, например, если происходит запись числа в переменную, которая не может уместить его полностью ввиду недостатка битов; или при присвоении отрицательного числа беззнаковой переменной.
Так же может возникнуть в таком коде (если Count=0):

var
i: Cardinal;
begin
for i := 0 to Count-1 do
 ...
end;


 
Сергей М. ©   (2007-02-02 14:27) [3]


> TRUNK ©   (02.02.07 14:14) [2]


> ERangeError возникает, например, если происходит запись
> числа в переменную, которая не может уместить его полностью
> ввиду недостатка битов; или при присвоении отрицательного
> числа беззнаковой переменной.


Ты эту траву больше не кури)


 
evvcom ©   (2007-02-02 14:34) [4]

> [0] DevilDevil ©   (02.02.07 13:21)
> "Range Checking", если убирать, то всё нормально работает

Это тебе только кажется :(


 
DrPass ©   (2007-02-02 15:18) [5]


> В конце концов пришёл к выводу, что ошибки возникают если
> ставить в опциях компилятора флажок "Range Checking", если
> убирать, то всё нормально работает

Скажем так - ошибки возникают в обоих случаях, но только при включенном Range Checking программа тебе об этом сообщает


 
clickmaker ©   (2007-02-02 15:25) [6]


> [5] DrPass ©   (02.02.07 15:18)
> только при включенном Range Checking программа тебе об этом сообщает

меньше знаешь - крепче спишь )


 
Kolan ©   (2007-02-02 15:26) [7]

> всё работало великолепно
запускаю, - RunTime Error 216


Аж мурашки по коже. Отвратительная ситуация... :(


 
Плохиш ©   (2007-02-02 16:31) [8]


> DevilDevil ©   (02.02.07 13:21)  

Это обращение к несуществующему объекту, скорее всего. Кстати, эта же ошибка возникает в Д7 при использовании строк в секции финализации модулей...


 
DevilDevil ©   (2007-02-02 17:48) [9]

Предлагаю всё же посуществу!
актуальны последние вопросы:
1) что из себя представляет эта опция компилятора
2) из-за чего чаще всего возникают такие ошибки
3) какие подводные камни могут мне встретиться при поиске места ошибки
4) пару советов, как обнаружить ошибку с "наименьшими потерями". Дело в том, что там очень много кода; преимущественно на ассмбелере.


 
DevilDevil ©   (2007-02-02 17:50) [10]

P.S. единственным информативным постом считаю Плохиш ©   (02.02.07 16:31) [8]


> TRUNK ©   (02.02.07 14:14) [2]
> Сергей М. ©   (02.02.07 14:27) [3]


Что он сказал неправильно?


 
evvcom ©   (2007-02-02 18:08) [11]

> [9] DevilDevil ©   (02.02.07 17:48)
> 1) что из себя представляет эта опция компилятора

Компилятор вставляет код проверки на выход за границы массивов.

> 2) из-за чего чаще всего возникают такие ошибки

при выходе за границы массива

> 3) какие подводные камни могут мне встретиться при поиске
> места ошибки

По-моему, там все элементарно. Смотришь стек, находишь самую верхнюю свою функцию. Дабл клик по ней. В подсвеченной строке или на одну выше идет обращение к массиву по "неправильному" индексу. Его и кури.

> 4) пару советов, как обнаружить ошибку

См. выше.

> преимущественно на ассмбелере

на этот код интересующая тебя галка не влияет.


 
evvcom ©   (2007-02-02 18:10) [12]

> [10] DevilDevil ©   (02.02.07 17:50)
> Что он сказал неправильно?

Все, что процитировано в [3]


 
DevilDevil ©   (2007-02-02 18:20) [13]


> evvcom ©   (02.02.07 18:08) [11]
>
> Компилятор вставляет код проверки на выход за границы массивов.
>


В1: только массивы? или ещё что то?
В2: а на массивы типа PMyArr влияет:
TMyArr = array[0..0] of SomeType;
PMyArr = ^TMyArr;


 
begin...end ©   (2007-02-02 18:30) [14]

> DevilDevil ©   (02.02.07 18:20) [13]

О1: Ещё что-то.
О2: Влияет.


 
evvcom ©   (2007-02-02 18:40) [15]

> [13] DevilDevil ©   (02.02.07 18:20)

O1: Блин, ну открой справку, да почитай:
The $R directive enables or disables the generation of range-checking code. In the {$R+} state, all array and string-indexing expressions are verified as being within the defined bounds, and all assignments to scalar and subrange variables are checked to be within range.
Я вспомнил только массивы, потому как только на них и наскакивал на эту ошибку. А за полной информацией обращайся к документации.


 
DevilDevil ©   (2007-02-02 18:46) [16]


> begin...end ©   (02.02.07 18:30) [14]
> О2: Влияет.


И как влияет? Как он range определяет?

P.S. в этом начерное ошибка.


 
begin...end ©   (2007-02-02 19:03) [17]

> DevilDevil ©   (02.02.07 18:46) [16]

В случае включённого Range Checking перед обращением к элементу массива типа TMyArr (в том числе и через указатель) компилятор вставляет код проверки вхождения индекса элемента в границы указанного диапазона, т.е. 0..0. Если индекс не равен 0, возбуждается исключение. Вот и всё.


 
DevilDevil ©   (2007-02-02 19:10) [18]

ну вот наверное и место ошибки!
посмотрю ночью сёдня


 
jack128 ©   (2007-02-02 20:06) [19]

evvcom ©   (02.02.07 14:34) [4]
Это тебе только кажется :(


Ну достаточно часто вижу в коде, в целом весьма не плохом, такие фрагменты:

PIntArray = array[0..0] of Integer;

begin
 ...
 if PIntArray(SamePointer)[10] <> 5 then
   Тря-ля-ля
end;

Причем по логике - код верен.  Но исключение естестенно поднимется.  Поэтому и предпочитаю декларации а-ля:
type
 PSameTypeArray = array[0..MaxInt div SizeOf(TSameType) - 1] of TSameType


 
jack128 ©   (2007-02-02 20:07) [20]

jack128 ©   (02.02.07 20:06) [19]
PSameTypeArray = array[0..MaxInt div SizeOf(TSameType) - 1] of TSameType

В смысле
 TSameTypeArray = array[0..MaxInt div SizeOf(TSameType) - 1] of TSameType;
 PSameTypeArray = ^SameTypeArray;

Сорри,  коньячек дает знать свое.


 
DevilDevil ©   (2007-02-02 20:11) [21]

> jack128 ©   (02.02.07 20:06) [19]
А нет ли возможности указать компиляторы, не проверять таким образом конкретые массивы?


 
jack128 ©   (2007-02-02 20:17) [22]

DevilDevil ©   (02.02.07 20:11) [21]
не проверять таким образом конкретые массивы?

нет.  Конкретные участки кода - можно.  

{$R-}
некий код

{$R+}


 
Vga ©   (2007-02-02 20:26) [23]

{$R-} в нужном юните. Дает эффект отключения галочки для одного юнита.


 
DevilDevil ©   (2007-02-02 21:09) [24]

Жесть вообще!!! Проблемы Range Checking были решены минут за 5. Ошибки возникали, например в строке:

var
 wptr2 : pword;
 newval : integer;

wptr2^ := newval;


решение следующее:
wptr2^ := word(newval);

фиг знает, почему так работает, там вообще вот какие строки:
           oldval := 0;
           if sptr^.length <> 0 then {моё}
           for lp := 0 to sptr^.length - 1 do
           begin
             newval := wptr2^ + oldval;
             wptr2^ := word(newval); {моё}
             oldval := newval;
             inc(wptr2);
           end;


Зато ошибок не выдаётся и то хорошо....
Ладно, буду тестировать на других файлах и опциях компилятора :)


 
DevilDevil ©   (2007-02-02 21:14) [25]

))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
Если выставить галку "Optimization", то возникает ошибка доступа к памяти...... в ассемблерном коде )))))))))))))))))))))


 
DevilDevil ©   (2007-02-02 21:22) [26]

Да, проверил, вроде при любых опциях компилятора (кроме "Optimization") всё работает. Теперь вопрос в следующем: "Как уберечь функцию от оптимизации". Понятно, что можно в начале модуля указать компилятору, чтобы он не оптимизировал код (кстати какой директивой?). Но мне хотелось бы, чтобы не оптимизировалась только одна функция; а весь остальной код модуля должен зависеть от глобальных настроек компилятора.


 
DevilDevil ©   (2007-02-02 21:32) [27]

Мдаааа........
Как ни старался, помог только {$OPTIMIZATION OFF} в начале модуля. Иначе либо зависает, либо выдаёт ошибку.

P.S. всем спасибо


 
DrPass ©   (2007-02-02 21:40) [28]


> Теперь вопрос в следующем: "Как уберечь функцию от оптимизации".
>  

Не использовать регистры DI, ESI, ESP, EBP и EBX в ассемблерном коде пробовал?


 
DevilDevil ©   (2007-02-03 00:43) [29]


> DrPass ©   (02.02.07 21:40) [28]


1) не я автор функции
2) чего там только не используется ;)


 
Германн ©   (2007-02-03 01:59) [30]

Лично я стараюсь никогда не выключать RangeChecking. Не смотря на рекомендации использовать её только на этапе отладки!


 
Anatoly Podgoretsky ©   (2007-02-03 10:35) [31]

> Германн  (03.02.2007 01:59:30)  [30]

Ни одну из этой группы в три чекбокса отключать не рационально



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

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

Наверх




Память: 0.55 MB
Время: 0.029 c
15-1170601610
Ricks
2007-02-04 18:06
2007.02.25
Куда девался пункт меню Project->Resources???


15-1170176379
Chort
2007-01-30 19:59
2007.02.25
Распределить текст по разным столбцам


2-1170530626
Лебедев
2007-02-03 22:23
2007.02.25
memo


8-1151000056
гость333
2006-06-22 22:14
2007.02.25
покадровое воспроизведение видео


2-1170545848
ssss
2007-02-04 02:37
2007.02.25
программу во все окно!