Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.02.25;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.046 c
2-1170416975
Елена
2007-02-02 14:49
2007.02.25
Application.Terminate


6-1158231851
Alexander_K
2006-09-14 15:04
2007.02.25
Как программно подконнектится?


2-1170668284
Defort
2007-02-05 12:38
2007.02.25
Крестик


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


2-1170432550
z[T]x
2007-02-02 19:09
2007.02.25
Master/Detail





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский