Текущий архив: 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.52 MB
Время: 0.04 c