OberonCore https://forum.oberoncore.ru/ |
|
++i + ++i в Обероне: недокументированное поведение? https://forum.oberoncore.ru/viewtopic.php?f=158&t=6978 |
Страница 1 из 1 |
Автор: | olenellus [ Воскресенье, 21 Апрель, 2024 16:27 ] |
Заголовок сообщения: | ++i + ++i в Обероне: недокументированное поведение? |
Определяем модуль Код: MODULE test; IMPORT Out; TYPE Counter = POINTER TO RECORD value: INTEGER; END; VAR i: Counter; PROCEDURE (i: Counter) pp(): INTEGER; BEGIN INC(i.value); RETURN i.value END pp; PROCEDURE (i: Counter) ppp(): INTEGER; BEGIN INC(i.value,2); RETURN i.value END ppp; PROCEDURE (i: Counter) PP(): Counter; BEGIN INC(i.value); RETURN i END PP; PROCEDURE Check(i1,i2,i3,i4: Counter); BEGIN Out.String('i1 = '); Out.Int(i1.value,0); Out.Ln; Out.String('i2 = '); Out.Int(i2.value,0); Out.Ln; Out.String('i3 = '); Out.Int(i3.value,0); Out.Ln; Out.String('i4 = '); Out.Int(i4.value,0); Out.Ln; END Check; PROCEDURE check(i1,i2,i3,i4: INTEGER); BEGIN Out.String('i1 = '); Out.Int(i1,0); Out.Ln; Out.String('i2 = '); Out.Int(i2,0); Out.Ln; Out.String('i3 = '); Out.Int(i3,0); Out.Ln; Out.String('i4 = '); Out.Int(i4,0); Out.Ln END check; BEGIN NEW(i); i.value := 10; Out.String('the initial value: '); Out.Int(i.value,0); Out.Ln; Out.String('the result of the operation pp + pp: '); Out.Int(i.pp() + i.pp(),0); Out.Ln; Out.String('the final value: '); Out.Int(i.value,0); Out.Ln; i.value := 10; Out.String('the initial value: '); Out.Int(i.value,0); Out.Ln; Out.String('the result of the operation ppp + pp: '); Out.Int(i.ppp() + i.pp(),0); Out.Ln; Out.String('the final value: '); Out.Int(i.value,0); Out.Ln; i.value := 10; Out.String('the initial value: '); Out.Int(i.value,0); Out.Ln; Out.String('the result of the operation pp + ppp: '); Out.Int(i.pp() + i.ppp(),0); Out.Ln; Out.String('the final value: '); Out.Int(i.value,0); Out.Ln; Out.Ln; i.value := 10; Out.String('the initial value with pointers: '); Out.Int(i.value,0); Out.Ln; Check( i.PP() , i.PP() , i.PP() , i.PP() ); Out.Ln; i.value := 10; Out.String('the initial value with values: '); Out.Int(i.value,0); Out.Ln; check( i.pp() , i.pp() , i.pp() , i.pp() ); Out.Ln END test. На выходе с Ofront+ и oo2c получаем: Код: the initial value: 10 the result of the operation pp + pp: 23 the final value: 12 the initial value: 10 the result of the operation ppp + pp: 25 the final value: 13 the initial value: 10 the result of the operation pp + ppp: 24 the final value: 13 the initial value with pointers: 10 i1 = 14 i2 = 14 i3 = 14 i4 = 14 the initial value with values: 10 i1 = 14 i2 = 13 i3 = 12 i4 = 11 Отсюда делаем вывод, что в процедурах вычисление аргументов идёт с конца списка, а в выражениях с оператором "+" — с начала. Как видно, если выражения с последствиями, порядок важен. Это где-нибудь вообще задокументировано или оставлено на откуп автора компилятора? В последнем случае получаем неопределённое поведение. |
Автор: | JackKatch [ Воскресенье, 21 Апрель, 2024 17:37 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
Могу ошибаться, но вроде бы Oftron+ это транслятор в Си. В Паскале, а следовательно и Обероне, параметры передаются слева на право, а в Си с права налево. Наверное в этом ошибка транслятора. Т.е. нужно сначала вычислить параметры i1, i2, i3, i4, а потом передавать в подпрограмму в обратном порядке. Тогда будет правильно т.е. 11, 12, 13, 14. Подождём вердикт авторов. |
Автор: | olenellus [ Воскресенье, 21 Апрель, 2024 17:53 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
Да, и Ofront+, и oo2c — это трансляторы в C. |
Автор: | arisu [ Воскресенье, 21 Апрель, 2024 20:12 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
это убешечка. и на самом деле порядок вычислений в выражении тоже не специфицирован. кажется, об этом в репорте где-то прямо сказано. |
Автор: | JackKatch [ Понедельник, 22 Апрель, 2024 14:38 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
Я в данном вопросе не специалист. Однопроходный (Виртовский) компилятор Оберон генерирует код сразу, т.е. обрабатывает выражения слева направо. Согласен с тем что документация "слабовата", многие вещи не определены явно, часто подразумеваются. |
Автор: | Oleg N. Cher [ Вторник, 23 Апрель, 2024 03:30 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
Да, это UB (неопределённое поведение) в чистом виде. Нигде в описании языка не гарантируется порядок вычисления параметров. Так что действительно оставлен на откуп авторов компилятора. Смысла делать в Ofront'е+ вычисление слева-направо, корёжа порядок параметров - не ощущаю. Возникнет много дополнительных сложностей. Избегайте кода, зависящего от порядка вычисления параметров. |
Автор: | arisu [ Вторник, 23 Апрель, 2024 10:28 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
сложностей-то сделать фиксированый порядок никаких особо: просто безусловный спилл во временные локалы, и дальше пусть компилятор сишечки это сам оптимизирует. но да, писать такой код — это плохо. к сожалению, как раз сделать надёжную диагностику подобного невозможно, потому что это проблема останова. а делать диагностику, которая работает только иногда — это вселять в программиста уверенность, что раз компилятор не предупредил, то ничего страшного: он же предупреждает обычно. вообще, функции с побочными эффектами — это плохо в принципе (хотя иногда и неизбежно). если есть возможность — лучше разделять на процедуру мутации, и функцию, которая возвращает результат последней мутации. чуть менее эффективно в плане получаемого кода, но проще в сопровождении, и меньше вероятность ошибок. |
Автор: | olenellus [ Вторник, 23 Апрель, 2024 15:28 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
arisu писал(а): это убешечка. и на самом деле порядок вычислений в выражении тоже не специфицирован. кажется, об этом в репорте где-то прямо сказано. Во всяком случае на фиксированном порядке в выражениях типа "A & B" Вирт как раз настаивал. Логично было бы перенести это правило ("если в первой позиции ноль, дальше можно не считать") на "*" для чисел и множеств и MOD. Хотя, сложности могут возникнуть, если на второй позиции в N*M Inf или NaN. Кстати, упомянутые компиляторы правильно отрабатывают Inf и NaN для типов REAL и LONGREAL, но это ведь тоже самодеятельность, не так ли? Что-то чем больше я смотрю, тем больше мне кажется, что железобетонная надёжность Оберонов слегка преувеличена, а бахвальство 20ти страничным описанием языка представляет собой некоторое лукавство, и работа по его уточнению и стандартизации ещё только предстоит. |
Автор: | arisu [ Среда, 24 Апрель, 2024 10:05 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
надёжность оберона вовсе не в том, что язык специфицирован до последней запятой. да и само понятие «надёжность» — оно, мне кажется, часто понимается неверно. оберон надёжный в том смысле, что программа на обероне или работает, или трапается. язык не позволит выйти за пределы массива, например, и радостно загадить случайный кусок памяти. также это был первый (или точно один из первых) язык, компилируемый в родной машинный код, и при этом со сборкой мусора. так что ошибки типа «use after free» тоже исключены. вот в этом и состоит надёжность языка: он не позволит ошибке в программе случайно разрушить чужие данные. причём достигается это без применения аппаратных средств разграничения доступа. и минималистичность самого языка тоже помогает: оберон действительно очень просто выучить, и на нём не особо получится писать в стиле: «я умею много трюков, и сейчас их все вам покажу!» сейчас отчего-то надёжность принято понимать как железобетонную защиту от программиста-идиота. а в обероне надёжность — это защита от непреднамеренных ошибок, которые может допустить кто угодно. от идиота оберон не особо защищён, потому что предполагается, что не надо идиотов к программированию допускать. так что определять порядок вычисления аргументов, например, в отчёте и не было нужды: предполагается, что программисту ещё на первом курсе рассказали, почему функции с побочными эффектами плохо, и почему следует избегать кода, где таких вызовов в выражении несколько. я сам немного упарываюсь по принципу: «UB быть не должно!», но это скорее личная заморочка. на надёжность языка и системы это влияет мало. в том же форте вообще никаких средств защиты нет. он даже указатели и целые никак не различает, ему всё равно. однако ж мои программы на форте не падают, и память не рушат. просто потому что надёжность программ на форте достигается методологией их создания. вот с обероном примерно так же. конечно, это и к любому другому языку применимо, но чем сложней сам язык — тем это будет сложнее сделать. |
Автор: | Trurl [ Среда, 24 Апрель, 2024 10:48 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
Oleg N. Cher писал(а): Да, это UB (неопределённое поведение) в чистом виде. Нет, это не оно, это другое. wikipedia писал(а): In computer programming, undefined behavior (UB) is the result of executing a program whose behavior is prescribed to be unpredictable, in the language specification to which the computer code adheres. This is different from unspecified behavior, for which the language specification does not prescribe a result, and implementation-defined behavior that defers to the documentation of another component of the platform (such as the ABI or the translator documentation).
|
Автор: | Александр Ильин [ Четверг, 09 Май, 2024 19:56 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
arisu писал(а): надёжность оберона... язык, компилируемый в родной машинный код, и при этом со сборкой мусора. так что ошибки типа «use after free» тоже исключены. Не исключены, но почти. Говорю как человек, искавший с дизассемблером баг, от которого программа на Oberon-2 падала в случайное время при сборке мусора. Оказалась опечатка в один пропущенный символ, и код писал опытный программист, совсем не идиот.
|
Автор: | arisu [ Суббота, 11 Май, 2024 19:33 ] |
Заголовок сообщения: | Re: ++i + ++i в Обероне: недокументированное поведение? |
ну, технически и хип в BBCB, например, можно нарезать в лапшу совершенно обычным кодом безо всякого SYSTEM, как показывал уважаемый Трурль. тем не менее — это редкость, и обычно для такого надо написать что-то оче странное, чтобы ударить в какой-нибудь corner case компилятора. увы, идеальных инструментов нет. но оберон можно считать хорошим приближением к идеалу, я думаю. ;-) |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |