OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Суббота, 04 Май, 2024 00:46

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
СообщениеДобавлено: Воскресенье, 21 Апрель, 2024 16:27 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 14
Определяем модуль
Код:
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

Отсюда делаем вывод, что в процедурах вычисление аргументов идёт с конца списка, а в выражениях с оператором "+" — с начала. Как видно, если выражения с последствиями, порядок важен.

Это где-нибудь вообще задокументировано или оставлено на откуп автора компилятора? В последнем случае получаем неопределённое поведение.


Последний раз редактировалось olenellus Воскресенье, 21 Апрель, 2024 17:52, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 21 Апрель, 2024 17:37 

Зарегистрирован: Пятница, 07 Май, 2021 11:06
Сообщения: 30
Могу ошибаться, но вроде бы Oftron+ это транслятор в Си. В Паскале, а следовательно и Обероне, параметры передаются слева на право, а в Си с права налево. Наверное в этом ошибка транслятора. Т.е. нужно сначала вычислить параметры i1, i2, i3, i4, а потом передавать в подпрограмму в обратном порядке. Тогда будет правильно т.е. 11, 12, 13, 14. Подождём вердикт авторов.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 21 Апрель, 2024 17:53 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 14
Да, и Ofront+, и oo2c — это трансляторы в C.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 21 Апрель, 2024 20:12 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
это убешечка. и на самом деле порядок вычислений в выражении тоже не специфицирован. кажется, об этом в репорте где-то прямо сказано.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 22 Апрель, 2024 14:38 

Зарегистрирован: Пятница, 07 Май, 2021 11:06
Сообщения: 30
Я в данном вопросе не специалист. Однопроходный (Виртовский) компилятор Оберон генерирует код сразу, т.е. обрабатывает выражения слева направо. Согласен с тем что документация "слабовата", многие вещи не определены явно, часто подразумеваются.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 23 Апрель, 2024 03:30 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 521
Откуда: Украина, Днепропетровская обл.
Да, это UB (неопределённое поведение) в чистом виде.

Нигде в описании языка не гарантируется порядок вычисления параметров.
Так что действительно оставлен на откуп авторов компилятора.

Смысла делать в Ofront'е+ вычисление слева-направо, корёжа порядок параметров - не ощущаю. Возникнет много дополнительных сложностей.

Избегайте кода, зависящего от порядка вычисления параметров.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 23 Апрель, 2024 10:28 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
сложностей-то сделать фиксированый порядок никаких особо: просто безусловный спилл во временные локалы, и дальше пусть компилятор сишечки это сам оптимизирует.

но да, писать такой код — это плохо. к сожалению, как раз сделать надёжную диагностику подобного невозможно, потому что это проблема останова. а делать диагностику, которая работает только иногда — это вселять в программиста уверенность, что раз компилятор не предупредил, то ничего страшного: он же предупреждает обычно.

вообще, функции с побочными эффектами — это плохо в принципе (хотя иногда и неизбежно). если есть возможность — лучше разделять на процедуру мутации, и функцию, которая возвращает результат последней мутации. чуть менее эффективно в плане получаемого кода, но проще в сопровождении, и меньше вероятность ошибок.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 23 Апрель, 2024 15:28 

Зарегистрирован: Вторник, 12 Март, 2024 20:31
Сообщения: 14
arisu писал(а):
это убешечка. и на самом деле порядок вычислений в выражении тоже не специфицирован. кажется, об этом в репорте где-то прямо сказано.

Во всяком случае на фиксированном порядке в выражениях типа "A & B" Вирт как раз настаивал. Логично было бы перенести это правило ("если в первой позиции ноль, дальше можно не считать") на "*" для чисел и множеств и MOD. Хотя, сложности могут возникнуть, если на второй позиции в N*M Inf или NaN. Кстати, упомянутые компиляторы правильно отрабатывают Inf и NaN для типов REAL и LONGREAL, но это ведь тоже самодеятельность, не так ли?

Что-то чем больше я смотрю, тем больше мне кажется, что железобетонная надёжность Оберонов слегка преувеличена, а бахвальство 20ти страничным описанием языка представляет собой некоторое лукавство, и работа по его уточнению и стандартизации ещё только предстоит.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Апрель, 2024 10:05 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
надёжность оберона вовсе не в том, что язык специфицирован до последней запятой. да и само понятие «надёжность» — оно, мне кажется, часто понимается неверно.

оберон надёжный в том смысле, что программа на обероне или работает, или трапается. язык не позволит выйти за пределы массива, например, и радостно загадить случайный кусок памяти. также это был первый (или точно один из первых) язык, компилируемый в родной машинный код, и при этом со сборкой мусора. так что ошибки типа «use after free» тоже исключены.

вот в этом и состоит надёжность языка: он не позволит ошибке в программе случайно разрушить чужие данные. причём достигается это без применения аппаратных средств разграничения доступа.

и минималистичность самого языка тоже помогает: оберон действительно очень просто выучить, и на нём не особо получится писать в стиле: «я умею много трюков, и сейчас их все вам покажу!»

сейчас отчего-то надёжность принято понимать как железобетонную защиту от программиста-идиота. а в обероне надёжность — это защита от непреднамеренных ошибок, которые может допустить кто угодно. от идиота оберон не особо защищён, потому что предполагается, что не надо идиотов к программированию допускать.

так что определять порядок вычисления аргументов, например, в отчёте и не было нужды: предполагается, что программисту ещё на первом курсе рассказали, почему функции с побочными эффектами плохо, и почему следует избегать кода, где таких вызовов в выражении несколько.

я сам немного упарываюсь по принципу: «UB быть не должно!», но это скорее личная заморочка. на надёжность языка и системы это влияет мало.

в том же форте вообще никаких средств защиты нет. он даже указатели и целые никак не различает, ему всё равно. однако ж мои программы на форте не падают, и память не рушат. просто потому что надёжность программ на форте достигается методологией их создания. вот с обероном примерно так же. конечно, это и к любому другому языку применимо, но чем сложней сам язык — тем это будет сложнее сделать.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 24 Апрель, 2024 10:48 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1429
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).


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB