Настройка компилятора. Преобразование типов.
Модератор: Модераторы
Настройка компилятора. Преобразование типов.
Привет всем.
Прошу помощи у гуру freepascal.
На данный момент стоит задача - портировать часть исходных кодов из borland pascal на freepascal.
Множество проблем уже решено.
Осталась самая малость:
В borland сплошь и рядом используется неявное приведение, если так и оставлять, то при запуске программы на этих местах прога падает.
По логам потом ясно на какой строчке падает и иду исправлять. Муторно и долго.
Итак, можно ли настроить компилятор, чтобы он выдавал ошибки, если происходит неявное преобразование?
пример
b : word;
s : string;
b := StrToInt(s); - тут упадет.
Прошу помощи у гуру freepascal.
На данный момент стоит задача - портировать часть исходных кодов из borland pascal на freepascal.
Множество проблем уже решено.
Осталась самая малость:
В borland сплошь и рядом используется неявное приведение, если так и оставлять, то при запуске программы на этих местах прога падает.
По логам потом ясно на какой строчке падает и иду исправлять. Муторно и долго.
Итак, можно ли настроить компилятор, чтобы он выдавал ошибки, если происходит неявное преобразование?
пример
b : word;
s : string;
b := StrToInt(s); - тут упадет.
Не должно падать.
Версия Вашего FreePascal и ОС. Желательно фрагмент падучего кода.
Версия Вашего FreePascal и ОС. Желательно фрагмент падучего кода.
Может падать только из-за Range Check Error, которые можно отключить - {$R-}.
Отловить неявные преобразования типов при присвоении целых разной размерности, по моему невозможно.
Отловить неявные преобразования типов при присвоении целых разной размерности, по моему невозможно.
Max Rusov писал(а):Может падать только из-за Range Check Error, которые можно отключить - {$R-}.
Отловить неявные преобразования типов при присвоении целых разной размерности, по моему невозможно.
Так WORD остался с прежним форматом (размером), а оно на BP у человека работало
Может действительно, в глобальных настройках IDE Borland Pascal было отключено Range Check Error.
Да, единственное, что я в этом коде вижу - это возможность переполнения. Если его допускать нельзя, то лучше поставить предварительную проверку. Или Try ... Except...
var b : byte;
b := b shl 1; // тут падал, при определенном значении b
function Crc16msb(pBuf : array of byte; lSize : Integer) : word;
s : word;
Crc16msb := integer(s shr
+ integer(s shl
; // тут падало
не спрашивайте что за код, было написано еще до меня. сейчас стоит задача портировать его и там таких ляпом навалом.
падало с ошибкой Range Check Error
{$R-} - это попробую
ОС - DOS 6.22
FreePascal for IDE GO32 V2 DOS
версия FP 1.0.10 2008/7/31
комиплятор 2.2.2
дебаггер GBD 6.1.1
b := b shl 1; // тут падал, при определенном значении b
function Crc16msb(pBuf : array of byte; lSize : Integer) : word;
s : word;
Crc16msb := integer(s shr
не спрашивайте что за код, было написано еще до меня. сейчас стоит задача портировать его и там таких ляпом навалом.
падало с ошибкой Range Check Error
{$R-} - это попробую
ОС - DOS 6.22
FreePascal for IDE GO32 V2 DOS
версия FP 1.0.10 2008/7/31
комиплятор 2.2.2
дебаггер GBD 6.1.1
Notus писал(а):var b : byte;
b := b shl 1; // тут падал, при определенном значении b
...
Ну да. При значении b >= 128 - падает, а при меньших нет. Это и есть Range Check Error.
FP menu: options->compiler... ->вкладка Generated Code. Убираем отметку на Range Checking. (правда я не знаю или это работает в вашей версии FP)
или в начале модуля прописываем {$R-}
Logo писал(а):FP menu: options->compiler... ->вкладка Generated Code. Убираем отметку на Range Checking.
И получаем ошибки, которые отлавливаться не будут, под названием "неправильные вычисления".
Vadim писал(а):И получаем ошибки, которые отлавливаться не будут, под названием "неправильные вычисления".
Естественно, а оно по логике так и было в начальной программе. Ведь все ошибки у человека связаны именно с превышением разрядности.
Спасибо за советы.
Такое дело. Компилируется перенесенный модуль в любом случае. В этих местах он падает только при выполнении программы, что совершенно ненужно.
я так понимаю {$R-} - позволит программе выполняться?
но хотелось бы исправить такие ошибки, тем более они явные и особых трудозатрат не потребуется ( трудности в их обнаружении).
Компилятор, получается, нельзя настроить на поиск неявных преобразований?
Такое дело. Компилируется перенесенный модуль в любом случае. В этих местах он падает только при выполнении программы, что совершенно ненужно.
я так понимаю {$R-} - позволит программе выполняться?
но хотелось бы исправить такие ошибки, тем более они явные и особых трудозатрат не потребуется ( трудности в их обнаружении).
Компилятор, получается, нельзя настроить на поиск неявных преобразований?
Notus писал(а):я так понимаю {$R-} - позволит программе выполняться?
Позволять то позволяет, но увеличивает во много раз вероятность получения ошибочность результата. Вот смотрите, что получается:
- если включена проверка соответствия диапазону (Check Range), то компилятор дополнительно включает в Вашу программу код, который проверяет каждое действие и как только Вы выходите за диапазон типа переменной, выдаётся сообщение об ошибке и работа программы останавливается. Например у Вас есть B: Byte; Вы делаете B:=255 {это пока нормально}, а потом Inc(B), то при включённой проверке {$R+} Вы получаете сообщение об ошибке и знаете, что здесь Вам тип надо поменять, например Byte на Word, чтобы продолжать работать с правильными данными. А вот если у Вас проверка отключена, т.е. стоит {$R-}, то Вы в результате последнего действия получаете в переменной вместо правильного значения 256, неправильное значение 0, т.к. разрядность переменной кончилась и счёт пошёл опять сначала. Это уже ошибкой не считается, вот только получив за свою работу вместо 256 долларов 0, Вы вряд ли останетесь довольны жизнью, да и жена Вас перестанет пускать домой с такой зарплатой.
Как видите, исправить ошибки программы Вам помогут не отключение тех или иных опций компилятора, а наоборот их включение, иначе ошибку программы Вы увидите только тогда, когда разгневанные клиенты придут Вас бить (и возможно ногами
Как мне видится, проблема у Вас отнюдь не в неявных преобразованиях, а в неправильных типах данных, которые не соответствуют диапазону проводимых вычислений, либо наоборот - в неправильном подборе алгоритмов вычисления, если определённо известно, что результаты не должны выходить из того или иного диапазона.
Ну, есть еще ряд алгоритмов, в которых целые и должны отсекаться при переполнении не вызывая ошибки - подсчет CRC и т.п. Не зная задачи нельзя утверждать что правильно.
Max Rusov писал(а):Ну, есть еще ряд алгоритмов, в которых целые и должны отсекаться при переполнении не вызывая ошибки - подсчет CRC и т.п. Не зная задачи нельзя утверждать что правильно.
+100
Абсолютно верно!!!
Понимаете, разрядность, приведенных вами, переменных осталась та же самая, что и была в Borland Pascal, здесь маловероятна проблема переноса. А очень часто сдвиги SSR, SSL в программах используют именно для маскирования или игнорирования некоторых разрядов переменных. Особенно если это программа для управлениями какими-то механизмами, то там это применяется, практически, всегда. Поэтому есть мнение, что изначально проверка на переполение была просто выключена. А так, для более полного ответа, нужно хоть что-то видеть из кода.
Кстати, помнится Borland рекомендовали после отладки программы, отключать все проверки, кроме "i/o error", это ускоряло работу программы. Не исключено, что именно это и было сделано в первоначальной версии.
Добавлено спустя 48 минут:
Вспомнил!!!
Inc(), Dec(), SsL, SsR в BP не генерировали ошибку!!! У же не помню, то ли там для них птичка была в опциях, то ли они вообще не вызывали переполнение, но точно не было ошибки.
Следовательно придется возле каждой такой строки отключать проверку.
Не путайте Range Check {$R+} и Overflow Check {$Q+}
Inc/Dec генерируют код переполнения при включенной опции "Overflow Check" {$Q+}. Shl/Shr - никогда не генерируют код переполнения.
Вроде, все одинаково и для Delphi и для FPC.
Inc/Dec генерируют код переполнения при включенной опции "Overflow Check" {$Q+}. Shl/Shr - никогда не генерируют код переполнения.
Вроде, все одинаково и для Delphi и для FPC.
Max Rusov писал(а):Не путайте Range Check {$R+} и Overflow Check {$Q+}
Inc/Dec генерируют код переполнения при включенной опции "Overflow Check" {$Q+}. Shl/Shr - никогда не генерируют код переполнения.
Вроде, все одинаково и для Delphi и для FPC.
Дошло, спасибо.
