OberonCore https://forum.oberoncore.ru/ |
|
XDS 2.6 beta release https://forum.oberoncore.ru/viewtopic.php?f=30&t=3739 |
Страница 4 из 6 |
Автор: | Александр Ильин [ Пятница, 06 Январь, 2012 11:57 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Евгений Темиргалеев писал(а): Александр Ильин писал(а): Вот, кстати, есть дополнительная польза от оптимизации. : ) Наверное, тут будет точнее --- есть дополнительная польза от мотивации Александра Ильина пользоваться компилятором XDS :) |
Автор: | igor [ Пятница, 06 Январь, 2012 11:59 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Ещё из отличий новой версии XDS. Раньше, вроде, никогда не всплывало сообщение: Код: * [*** 0.00 F193] По всей видимости это связано с проверкой согласованности импорта. Интересно, а раньше это не проверялось? Или проверялось и по тихому перекомпилировались все модули, которые импортируют этот?
* generation of new symbol file not allowed |
Автор: | Александр Ильин [ Пятница, 06 Январь, 2012 12:03 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
igor писал(а): Ещё из отличий новой версии XDS. Раньше, вроде, никогда не всплывало сообщение: Не, это всегда было. Надо включить опцию CHANGESYM (см. в xc.hlp).Код: * [*** 0.00 F193] * generation of new symbol file not allowed Её выключают, чтобы запретить компилятору менять интерфейс модулей. Интерфейс может быть зафиксирован в связи с тем, что определения (definition modules) отдали заказчику, или наоборот, если определения получены от третьих лиц. |
Автор: | igor [ Пятница, 06 Январь, 2012 12:40 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Александр Ильин писал(а): igor писал(а): Ещё из отличий новой версии XDS. Раньше, вроде, никогда не всплывало сообщение: ... Не, это всегда было. Надо включить опцию CHANGESYM (см. в xc.hlp). Включил у себя эту опцию |
Автор: | GameHunter [ Пятница, 06 Январь, 2012 13:54 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Да, Вы нашли мою смысловую ошибку. Интересно, а много ещё возможно ошибок, не вылезающих в отладочном режиме? В дельфях я такого вроде бы не встречал... С меня чай, как и обещано |
Автор: | Александр Ильин [ Пятница, 06 Январь, 2012 14:10 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
GameHunter писал(а): В дельфях я такого вроде бы не встречал... В Delphi неинициализированные стековые переменные работают точно так же, и точно так же могут давать псевдослучайные сбои. А вот при выделении под объект динамической памяти там обязательно затирается нулями весь блок.
|
Автор: | Александр Ильин [ Пятница, 06 Январь, 2012 15:12 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Александр Ильин писал(а): Чтобы исправить ошибку, нужно в строке 165 модуля GeneralParticle заменить "PassedDistance:=0;" на "r.PassedDistance:=0;". Alexey Veselovsky обратил внимание на то, что локальную переменную PassedDistance тоже надо инициализировать, так как она далее используется в выражении PassedDistance:=PassedDistance+...Поэтому строку "r.PassedDistance:=0;" надо добавить рядом с "PassedDistance:=0;", а не заменить одно на другое, как я написал ранее. Спасибо Alexey Veselovsky за внимательность! |
Автор: | Александр Ильин [ Пятница, 06 Январь, 2012 19:33 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Что-то я разошёлся! Давно не работал с дизассемблером, так даже понравилось. Удалось надёжно воспроизвести ещё одну ошибку, о которую я встречал ранее, да ещё и в минимальном проекте. Вот код: Код: <* GENPTRINIT+ *> (* Make sure local pointers are initialized, including RECORD fields. *) Для компиляции выполнить: xc =make Main.ob2<* PROCINLINE+ *> (* Allow procedure inlining. *) <* CHANGESYM+ *> <* MAIN+ *> MODULE Main; (* ------------------------------------------------------------------------ * (C) 2012 by Alexander Iljin * ------------------------------------------------------------------------ *) IMPORT Out; TYPE (* A stack-based RECORD type with a POINTER field. *) Writer = RECORD ptr: POINTER TO ARRAY OF CHAR; (* any pointer type will do *) END; PROCEDURE InitModule; (* This procedure will be inlined. *) VAR wr: Writer; BEGIN (* Since GENPTRINIT is ON, the field wr.ptr must be set NIL, but that * does not happen if the procedure is inlined. The compiler simply does * not generate the initialization code (typically that would be a "push 0" * instruction), and whatever is in the stack is left in the pointer field. * In real-life programs this leads to random 'invalid location' traps. *) IF wr.ptr # NIL THEN Out.String('Error!'); ELSE Out.String('Test passed.'); END; END InitModule; BEGIN InitModule; END Main. Для запуска: main.exe Выдаст "Error!" для XDS 2.50, 2.51, 2.60 beta. Суть в том, что при включенной опции GENPTRINIT должны зануляться все локальные указатели, в том числе находящиеся внутри стековых RECORD'ов. И это происходит, но только в том случае, если процедура не заинлайнена. Если процедура инлайнится, то локальная инициализация не происходит, и на месте указателей имеем случайный стековый мусор. |
Автор: | Александр Ильин [ Пятница, 06 Январь, 2012 19:47 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Вот ещё баг, полученный упрощением предыдущего: Код: <* GENPTRINIT+ *> (* Make sure local pointers are initialized, including RECORD fields. *) Здесь вместо стекового RECORD имеем обычную локальную переменную-указатель. При включенном GENPTRINIT её значение должно быть однозначно определено: NIL. Однако, XDS 2.50, 2.51 и 2.60 beta при запуске показывают совершенно неожиданный результат: "#RTS: unhandled exception #3: invalid location".<* PROCINLINE+ *> (* Allow procedure inlining. *) <* CHANGESYM+ *> <* MAIN+ *> MODULE Main; (* ------------------------------------------------------------------------ * (C) 2012 by Alexander Iljin * ------------------------------------------------------------------------ *) IMPORT Out; PROCEDURE InitModule; (* This procedure will be inlined. *) VAR ptr: POINTER TO ARRAY OF CHAR; BEGIN (* Since GENPTRINIT is ON, the field wr.ptr must be set NIL, but that * does not happen if the procedure is inlined. The compiler simply does * not generate the initialization code (typically that would be a "push 0" * instruction), and whatever is in the stack is left in the pointer field. * In real-life programs this leads to random 'invalid location' traps. *) IF ptr # NIL THEN Out.String('Error!'); ELSE Out.String('Test passed.'); END; END InitModule; BEGIN InitModule; END Main. Оказывается, компилятор, не долго думая, просто заменяет код процедуры на пару инструкций: Код: push 3 По его мнению, тут однозначно будет трап, так что даже нет смысла генерировать код. А ведь код вполне осмысленный. Более того, нет даже попытки разыменования указателя ptr, идёт только лишь сравнение его с NIL. Трапу просто неоткуда взяться.call X2C_TRAP_F Интересно, что XDS 2.50 и 2.51 выдают при компиляции предупреждение Код: * [Main.ob2 30.07 W304] Это вполне справедливо, хотя при включенном GENPTRINIT этого предупреждения тоже быть не должно.* possibly used before definition "ptr" IF $ptr # NIL THEN А XDS 2.60 beta уже дополнительно предупреждает о том нехорошем действии, что он задумал: Код: * [Main.ob2 30.11 W915] Да, он собирается поднять там исключение. Почему? Зачем? Разыменования указателя как не было, так и нет.* invalidLocation exception will be raised here IF ptr $# NIL THEN PS: 2.50 и 2.51 тоже выдают предупреждение о том, что будет исключение, но только если отключить PROCINLINE. |
Автор: | igor [ Воскресенье, 15 Январь, 2012 13:40 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Код: PROCEDURE GetChar (): CHAR; Почему в первой строчке всё OK, а во второй whole overflow? Какая компилятору разница? (XDS v2.60 beta)BEGIN RETURN CHR(65); (* "A" *) END GetChar; PROCEDURE Do*; VAR x: LONGINT; ch: CHAR; BEGIN ch := CHR(65); x := 505 * ORD(ch); (* ok *) x := 505 * ORD(GetChar()); (* whole overflow *) END Do; На практике решил пролемку так: Код: x := LONG(505) * ORD(GetChar()); (* ok *)
|
Автор: | Comdiv [ Понедельник, 16 Январь, 2012 12:17 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Если INTEGER и CHAR одинаковой разрядности, то понятно. В 1-м присваивании компилятор знает что значение ch - мало, и переполнения быть не может. Во 2-м присваивании значение 2-го множителя ему неизвестно, поскольку для процедуры Do считает функцию GetChar чёрным ящиком. И Вместо LONG(505) 505L не подойдёт? |
Автор: | igor [ Понедельник, 16 Январь, 2012 13:04 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Comdiv писал(а): Если INTEGER и CHAR одинаковой разрядности, то понятно. В данном контексте тип INTEGER 16-битный, а тип CHAR 8-битный (т. е. они разной разрядности).Comdiv писал(а): В 1-м присваивании компилятор знает что значение ch - мало, и переполнения быть не может. Во 2-м присваивании значение 2-го множителя ему неизвестно, поскольку для процедуры Do считает функцию GetChar чёрным ящиком. И переменная ch, и функция GetChar() имеют одинаковый тип CHAR, известный уже на этапе компиляции. И даже если бы это было не так, то всё-равно, в обоих случаях функция ORD() возвращает результат типа INTEGER, и никакой другой.Comdiv писал(а): И Вместо LONG(505) 505L не подойдёт? Нет, 505 - это десятичное число. Тогда, уж, лучше было бы записать 1F9L. Но это в Компонентном Паскале, а XDS не поддерживает КП.
|
Автор: | igor [ Понедельник, 16 Январь, 2012 13:10 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Кстати, константу 505 я для примера выбрал не случайно. Если значение этой константы уменьшить хотя бы на единицу, то произведение (504 * 65) будет меньше MAX(INTEGER), и переполнение не наступает в обоих случаях. Собственно, вопрос даже не в том, "почему наступает" или "почему не наступает", а в том, почему по разному себя ведёт. |
Автор: | Евгений Темиргалеев [ Понедельник, 16 Январь, 2012 13:19 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Предположение: 1) В первой строчке компилятор оптимизирует, не выполняя умножение. 2) Во второй выполняет, и, соответсвенно, ругается, что INTEGER*INTEGER->INTEGER даёт переполнение. Попробуйте дизассемблировать первую строчку. Может там будет просто x := 32825 |
Автор: | igor [ Понедельник, 16 Январь, 2012 13:29 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
"Оптимизация-шмоптимизация" (С) Info21 Евгений Темиргалеев писал(а): Попробуйте дизассемблировать первую строчку. Может там будет просто x := 32825 Сворачивание констант? Да, надо будет посмотреть на досуге.
|
Автор: | Info21 [ Понедельник, 16 Январь, 2012 14:43 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
igor писал(а): ... а XDS не поддерживает КП пока.
|
Автор: | Александр Ильин [ Понедельник, 16 Январь, 2012 17:04 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Евгений Темиргалеев писал(а): Предположение: Совершенно верное предположение. Это видно и без дизассемблера, достаточно добавить вывод x (Out.Int) и почитать предупреждения компилятора:1) В первой строчке компилятор оптимизирует, не выполняя умножение. 2) Во второй выполняет, и, соответсвенно, ругается, что INTEGER*INTEGER->INTEGER даёт переполнение. Попробуйте дизассемблировать первую строчку. Может там будет просто x := 32825 Код: * [Test.ob2 15.04 W900]
* redundant code eliminated $ch := CHR(65); * [Test.ob2 16.04 W900] * redundant code eliminated $x := 505 * ORD(ch); (* ok *) * [Test.ob2 16.19 W314] * variable "ch" has compile time defined value here x := 505 * ORD($ch); (* ok *) * [Test.ob2 17.12 W314] * variable "x" has compile time defined value here Out.Int($x, 0); |
Автор: | Comdiv [ Понедельник, 16 Январь, 2012 17:36 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Info21 писал(а): igor писал(а): ... а XDS не поддерживает КП пока. |
Автор: | igor [ Понедельник, 16 Январь, 2012 19:21 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Александр Ильин писал(а): Евгений Темиргалеев писал(а): Попробуйте дизассемблировать первую строчку. Может там будет просто x := 32825 Совершенно верное предположение. Это видно и без дизассемблера:Код: * [Test.ob2 16.04 W900] * redundant code eliminated $x := 505 * ORD(ch); (* ok *) * [Test.ob2 16.19 W314] * variable "ch" has compile time defined value here x := 505 * ORD($ch); (* ok *) * [Test.ob2 17.12 W314] * variable "x" has compile time defined value here Out.Int($x, 0); Из отчёта, предоставленного Александром, следует, что не только первая строчка вычисляется на этапе компиляции, но и вторая тоже. Получается, что различия не связаны с CompileTime или RunTime. То есть, в обоих случаях значение переменной "x" has compiler time defined. Формула INTEGER*INTEGER->INTEGER для обоих случаев одна и та же. Тем не менее, результат обработки этих двух строк компилятором различный. Очевидное различие в обработке заключается в том, что в первом случае результат произведения неявно преобразуется к типу LONGINT, а во втором случае нет. Двойные стандарты, какбЭ |
Автор: | Info21 [ Понедельник, 16 Январь, 2012 19:37 ] |
Заголовок сообщения: | Re: XDS 2.6 beta release |
Comdiv писал(а): Info21 писал(а): igor писал(а): ... а XDS не поддерживает КП пока. |
Страница 4 из 6 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |