![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Project/Options/Compiler/ RANGE CHECKING
DevilDevil © (2007-02-02 13:21:00)Довольно долго мучился переделывал одну библиотеку, довёл до нужного мне состояния; всё работало великолепно. Переношу полученную библиотеку в новый проект, запускаю, - RunTime Error 216 (это ошибка доступа к памяти). Долго мучился, перекидывал проект из папки в папку, менял опции компилятора.... то работает, то НЕТ. В конце концов пришёл к выводу, что ошибки возникают если ставить в опциях компилятора флажок "Range Checking", если убирать, то всё нормально работает. Так вот собственно вопросы:
1) что из себя представляет эта опция компилятора
2) из-за чего чаще всего возникают такие ошибки
3) какие подводные камни могут мне встретиться при поиске места ошибки
4) пару советов, как обнаружить ошибку с "наименьшими потерями". Дело в том, что там очень много кода; преимущественно на ассмбелере.
Заранее Спасибо!
Anatoly Podgoretsky (2007-02-03 10:35:00) [1]> Германн (03.02.2007 01:59:30) [30]
Ни одну из этой группы в три чекбокса отключать не рационально
Германн (2007-02-03 01:59:00) [2]Лично я стараюсь никогда не выключать RangeChecking. Не смотря на рекомендации использовать её толькона этапе отладки!
DevilDevil (2007-02-03 00:43:00) [3]
> DrPass © (02.02.07 21:40) [28]
1) не я автор функции
2) чего там только не используется ;)
DrPass (2007-02-02 21:40:00) [4]
> Теперь вопрос в следующем: "Как уберечь функцию от оптимизации".
>
Не использовать регистры DI, ESI, ESP, EBP и EBX в ассемблерном коде пробовал?
DevilDevil (2007-02-02 21:32:00) [5]Мдаааа........
Как ни старался, помог только {$OPTIMIZATION OFF} в начале модуля. Иначе либо зависает, либо выдаёт ошибку.
P.S. всем спасибо
DevilDevil (2007-02-02 21:22:00) [6]Да, проверил, вроде при любых опциях компилятора (кроме "Optimization") всё работает. Теперь вопрос в следующем: "Как уберечь функцию от оптимизации". Понятно, что можно в начале модуля указать компилятору, чтобы он не оптимизировал код (кстати какой директивой?). Но мне хотелось бы, чтобы не оптимизировалась только одна функция; а весь остальной код модуля должен зависеть от глобальных настроек компилятора.
DevilDevil (2007-02-02 21:14:00) [7]))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
Если выставить галку "Optimization", то возникает ошибка доступа к памяти...... в ассемблерном коде )))))))))))))))))))))
DevilDevil (2007-02-02 21:09:00) [8]Жесть вообще!!! Проблемы 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;
Зато ошибок не выдаётся и то хорошо....
Ладно, буду тестировать на других файлах и опциях компилятора :)
Vga (2007-02-02 20:26:00) [9]{$R-} в нужном юните. Дает эффект отключения галочки для одного юнита.
jack128 (2007-02-02 20:17:00) [10]DevilDevil © (02.02.07 20:11) [21]
не проверять таким образом конкретые массивы?
нет. Конкретные участки кода - можно.
{$R-}
некий код
{$R+}
DevilDevil (2007-02-02 20:11:00) [11]> jack128 © (02.02.07 20:06) [19]
А нет ли возможности указать компиляторы, не проверять таким образом конкретые массивы?
jack128 (2007-02-02 20:07:00) [12]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;
Сорри, коньячек дает знать свое.
jack128 (2007-02-02 20:06:00) [13]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
DevilDevil (2007-02-02 19:10:00) [14]ну вот наверное и место ошибки!
посмотрю ночью сёдня
begin...end (2007-02-02 19:03:00) [15]> DevilDevil © (02.02.07 18:46) [16]
В случае включённого Range Checking перед обращением к элементу массива типа TMyArr (в том числе и через указатель) компилятор вставляет код проверки вхождения индекса элемента в границы указанного диапазона, т.е. 0..0. Если индекс не равен 0, возбуждается исключение. Вот и всё.
DevilDevil (2007-02-02 18:46:00) [16]
> begin...end © (02.02.07 18:30) [14]
> О2: Влияет.
И как влияет? Как он range определяет?
P.S. в этом начерное ошибка.
evvcom (2007-02-02 18:40:00) [17]> [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.
Я вспомнил только массивы, потому как только на них и наскакивал на эту ошибку. А за полной информацией обращайся к документации.
begin...end (2007-02-02 18:30:00) [18]> DevilDevil © (02.02.07 18:20) [13]
О1: Ещё что-то.
О2: Влияет.
DevilDevil (2007-02-02 18:20:00) [19]
> evvcom © (02.02.07 18:08) [11]
>
> Компилятор вставляет код проверки на выход за границы массивов.
>
В1: только массивы? или ещё что то?
В2: а на массивы типа PMyArr влияет:
TMyArr = array[0..0] of SomeType;
PMyArr = ^TMyArr;
evvcom (2007-02-02 18:10:00) [20]> [10] DevilDevil © (02.02.07 17:50)
> Что он сказал неправильно?
Все, что процитировано в [3]