Автор Тема: Чем Вирту WITH не угодил?  (Прочитано 85806 раз)

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #240 : Январь 29, 2013, 04:30:13 pm »
... на  p.x := 42 программа должна рухнуть.

В Обероне-07 в реализации от akron1 действительно падает в этом месте.
MODULE TypeCrashTest;

IMPORT RTL, In, Out;

TYPE
  P  = POINTER TO R;
  R  = RECORD END;
  P1 = POINTER TO R1;
  R1 = RECORD (R) x: INTEGER END;

VAR p:P; p1:P1;

BEGIN
  NEW(p1);
  p := p1;
  p(P1).x := 1;
  p1.x := 2;
  NEW(p);
  p(P1).x := 42; (*havoc!!*)
END TypeCrashTest.

Было бы очень странно если б оно не падало:
Цитировать
The typeguard v(T0) asserts that v is of type T0, i.e. it aborts program execution, if it is not of type T0.
(пункт 8.1 сообщения о языке)

Собственно тут даже присваивания не нужно. Достаточно самого факта проверки. Ну, то есть достаточно было бы так:
p1:=p(P1);
Y = λf.(λx.f (x x)) (λx.f (x x))

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #241 : Январь 29, 2013, 04:41:03 pm »
Было бы очень странно если б оно не падало:

В смысле? Там же обычное приведение к наследнику, коим и является (по факту) p. В данном примере похоже на багу компилятора.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #242 : Январь 29, 2013, 04:47:07 pm »
Было бы очень странно если б оно не падало:

В смысле? Там же обычное приведение к наследнику, коим и является (по факту) p. В данном примере похоже на багу компилятора.
Сказано же:
Цитировать
it aborts program execution

Не удалось привести тип? Давай, досвидания - креш.
Y = λf.(λx.f (x x)) (λx.f (x x))

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #243 : Январь 29, 2013, 04:48:49 pm »
Не удалось привести тип? Давай, досвидания - креш.

Почему не удалось-то? Посмотри пример - там создается (NEW) наследник и к нему же идет приведение (через указатель на базу).

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #244 : Январь 29, 2013, 04:52:13 pm »
Не удалось привести тип? Давай, досвидания - креш.

Почему не удалось-то? Посмотри пример - там создается (NEW) наследник и к нему же идет приведение (через указатель на базу).

Там создается предок и его пытаются привести к наследнику:
NEW(p);
p(P1).x := 42; (*havoc!!*)

p имеет такой тип:
P  = POINTER TO R;
R  = RECORD END;

И приводят его к p1, который имеет такой тип:
P1 = POINTER TO R1;
R1 = RECORD (R) x: INTEGER END;

Вопросы? Пожелания? Коментарии?
Y = λf.(λx.f (x x)) (λx.f (x x))

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #245 : Январь 29, 2013, 05:09:04 pm »
Там создается предок и его пытаются привести к наследнику:

Где???
P1 = POINTER TO R1;
R1 = RECORD (R) x: INTEGER END;

Еще раз по-русски: P1 это указатель на R1, являющуюся расширением R. Т.е. создается R1. И к ней же кастается.

NEW(p);

Посмотри оригинал - там NEW(p1);

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #246 : Январь 29, 2013, 05:13:04 pm »
Там создается предок и его пытаются привести к наследнику:

Где???
P1 = POINTER TO R1;
R1 = RECORD (R) x: INTEGER END;

Еще раз по-русски: P1 это указатель на R1, являющуюся расширением R. Т.е. создается R1. И к ней же кастается.

NEW(p);

Посмотри оригинал - там NEW(p1);

Какой тупняк у нас веселый :-)

Цитировать
  NEW(p1);
  p := p1;
  p(P1).x := 1;
  p1.x := 2;
  NEW(p);
  p(P1).x := 42; (*havoc!!*)

Ну и где тут NEW(p1) ? ;-)
Y = λf.(λx.f (x x)) (λx.f (x x))

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #247 : Январь 29, 2013, 05:15:42 pm »
Ну и где тут NEW(p1) ? ;-)

Фуцк! У меня скроллер в оригинальном сообщении в аккурат скрывал второй NEW.

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #248 : Январь 29, 2013, 05:17:19 pm »
Ну и где тут NEW(p1) ? ;-)

Фуцк! У меня скроллер в оригинальном сообщении в аккурат скрывал второй NEW.
Вот что бывает когда весь логический кусок кода не влазит на один экран!
Y = λf.(λx.f (x x)) (λx.f (x x))

trurl

  • Full Member
  • ***
  • Сообщений: 133
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #249 : Январь 30, 2013, 05:33:10 am »
это не то, что ожидается от такой конструкции.
А что ожидается ?

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #250 : Январь 30, 2013, 01:54:43 pm »
А что ожидается ?

Ожидается проверка типа (один раз) и использование переменной проверенного типа (множество раз). Без трапов.

trurl

  • Full Member
  • ***
  • Сообщений: 133
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #251 : Январь 30, 2013, 06:09:39 pm »
Совсем без трапов не бывает. Никто же не помешает сделать p := NIL; p.x :=42;

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #252 : Январь 30, 2013, 06:10:40 pm »
Совсем без трапов не бывает. Никто же не помешает сделать p := NIL; p.x :=42;
А разименовывание нулевого указателя/ссылки это разве трап? По крайней мере в Обероне-07, вроде как нет. Никакого трапа не требуется.
Y = λf.(λx.f (x x)) (λx.f (x x))

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #253 : Январь 30, 2013, 06:59:00 pm »
Совсем без трапов не бывает. Никто же не помешает сделать p := NIL; p.x :=42;

Здесь есть принципиальная разница. Язык разрешает занулять поинтеры. Поэтому трап в этом случае вполне ожидаем. Но язык не позволяет написать p := pBase, если p имеет тип указателя на наследника (он таким становится после проверки WITH). То, что есть неявные средства поработать с p "опять" как с указателем на базовый тип - изъян дизайна. Который довольно легко лечится без кардинальной передлки языка. Решений предлагалось несколько. Но Вирт, как всегда, предпочел лечить проблему избавлением от проблемной конструкции. Хотя может он был даже и не в курсе проблемы - просто выпилил WITH, потому что в данный момент оно ему не надо.

trurl

  • Full Member
  • ***
  • Сообщений: 133
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #254 : Январь 31, 2013, 06:00:11 am »
Предлагаемые лекарства сводятся к удалению WITH из языка и введению новой конструкции с другой семантикой. Первую часть плана Вирт уже выполнил. :)