Oberon space
General Category => Общий раздел => Тема начата: ilovb от Апрель 26, 2012, 10:32:09 am
-
http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/Oberon07.pdf (http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/Oberon07.pdf)
The With statement has been eliminated.
-
Я конечно понимаю, что одноветочный WITH из оригинального Оберона мало полезен. Но ведь можно было многоветочный из Oberon 2 взять
-
The With statement has been eliminated.
Стремление к упрощению. Я бы упростил до WHILE DO и DO WHILE или, вообще до расширенного универсального FOR.
-
А при чем тут циклы?
-
А при чем тут циклы?
Я к тому, что для упрощения можно оставить только WHILE DO, DO WHILE, FOR, IF-THEN-ELSIF-ELSE.
-
Т.е. сделать в них охрану типа? Мне думается что это сильно усложнит компилятор...
-
неуклюжая конструкция, хватает логического оператора is вместе с if ом - IF btn IS button THEN .....
-
Эээ нееее :)
Проба типа не отменяет охрану типа :)
-
Вот кстати многоветочный WITH объединяет в себе и пробу и охрану. ;)
-
Эээ нееее :)
Проба типа не отменяет охрану типа :)
Я не говорю, что отменяет, я говорю что хватает...
-
Вот хороший пример для обсуждения (из книги "Проект Оберон"):
PROCEDURE Handle (F: Display.Frame; VAR M: Display.FrameMsg);
VAR F1: Frame;
BEGIN
WITH F: Frame DO
IF M IS Oberon.InputMsg THEN
WITH M: Oberon.InputMsg DO
IF M.id = Oberon.track THEN Edit(F, M.X, M.Y, M.keys)
ELSIF M.id = Oberon.consume THEN
IF F.car # 0 THEN Write(F, M.ch, M.fnt, M.col, M.voff) END
END
END
ELSIF M IS Oberon.ControlMsg THEN
WITH M: Oberon.ControlMsg DO 92
IF M.id = Oberon.defocus THEN Defocus(F)
ELSIF M.id = Oberon.neutralize THEN Neutralize(F)
END
END
ELSIF M IS Oberon.SelectionMsg THEN
WITH M: Oberon.SelectionMsg DO GetSelection(F, M.text, M.beg, M.end, M.time) END
ELSIF M IS Oberon.CopyOverMsg THEN
WITH M: Oberon.CopyOverMsg DO CopyOver(F, M.text, M.beg, M.end) END
ELSIF M IS Oberon.CopyMsg THEN
WITH M: Oberon.CopyMsg DO Copy(F, F1); M.F := F1 END
ELSIF M IS MenuViewers.ModifyMsg THEN
WITH M: MenuViewers.ModifyMsg DO Modify(F, M.id, M.dY, M.Y, M.H) END
ELSIF M IS UpdateMsg THEN
WITH M: UpdateMsg DO
IF F.text = M.text THEN Update(F, M) END
END
END
END
END Handle;
Тут приходится делать и пробу и охрану.
В Обероне 07 вместо:
WITH M: Oberon.CopyOverMsg DO CopyOver(F, M.text, M.beg, M.end) END
будет:
M(Oberon.CopyOverMsg).CopyOver(F, M.text, M.beg, M.end)
А в Обероне 2 весь ELSIF IS WITH заменится на один многоветочный WITH.
-
Я не говорю, что отменяет, я говорю что хватает...
Это как посмотреть. Некоторые ошибки в рантайм пролезут
-
Чет я не так выразился... В рантайм они и с WITH пролезут, но по оному будут локализованы в точке охраны типа. А без WITH... я даже не знаю, что произойдет :D
-
Естественно... должно быть кастование типа as (WITH это комбинация is и as растянутая на некоторую последовательность действий...)
-
В Обероне 07 вместо:
WITH M: Oberon.CopyOverMsg DO CopyOver(F, M.text, M.beg, M.end) END
будет:
M(Oberon.CopyOverMsg).CopyOver(F, M.text, M.beg, M.end)
Фу ты черт хрень написал :(
В Обероне 07 так будет:
CopyOver(F, M(Oberon.CopyOverMsg).text, M(Oberon.CopyOverMsg).beg, M(Oberon.CopyOverMsg).end)
-
Я не говорю, что отменяет, я говорю что хватает...
Вот только компилятор не даст так написать. ;)
Или даст? ???
-
ну... и проку бы было намного больше если бы была разрешена множественная охрана WITH a:Checkbox, b:Radiogroup, c:Button DO....
-
А смысл?
-
не плодить ветки под каждое кастование...
-
Ааааа понял :)
WITH a:Checkbox, b:Radiogroup, c:Button DO...
мне привиделось:
WITH a:Checkbox, a:Radiogroup, a:Button DO....
;D
У меня внимательность сегодня хромает ;D
-
Мне нравится ваше предложение :)
Компилятор это не усложнит, а WITH мощнее становится.
-
http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/Oberon07.pdf (http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/Oberon07.pdf)
The With statement has been eliminated.
На оберонкоровском форуме обсуждали уже -- этот оператор WITH в реализации блекбокса приводил к порче памяти из-за неправильных кастов.
Там же было упомянуто, что в обероне-07 Вирт убрал этот WITH, возможно из-за такой уязвимости...
-
Т.е. его трудно правильно реализовать?
Можно ссылочку, если знаете в какой ветке это обсуждалось?
-
http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/Oberon07.pdf (http://www.inf.ethz.ch/personal/wirth/Articles/Oberon/Oberon07.pdf)
The With statement has been eliminated.
На оберонкоровском форуме обсуждали уже -- этот оператор WITH в реализации блекбокса приводил к порче памяти из-за неправильных кастов.
Там же было упомянуто, что в обероне-07 Вирт убрал этот WITH, возможно из-за такой уязвимости...
Веселое дело, вы хотите сказать, что его удалили только из за того что у создателей реализации росли руки не из того места?.... еть... радует , то что они хотя бы складывать умеют а то не видать юзерам операции сложения.... а коровцы нашли бы и под это логичное объяснение...
-
В ЧЯ и FOR неправильно реализован на сколько я помню :)
Значит его тоже в мусорку ;)
-
Веселое дело, вы хотите сказать, что его удалили только из за того что у создателей реализации росли руки не из того места?.... еть... радует , то что они хотя бы складывать умеют а то не видать юзерам операции сложения.... а коровцы нашли бы и под это логичное объяснение...
например.. на .... складывать если этого даже Вирт не умеет...
-
В Обероне 07 так будет:
CopyOver(F, M(Oberon.CopyOverMsg).text, M(Oberon.CopyOverMsg).beg, M(Oberon.CopyOverMsg).end)
Можно такM1 := M(Oberon.CopyOverMsg);
CopyOver(F, M1.text, M1.beg, M1.end)
-
На Оберонкоре Трурль показывал как с помощью WITH завалить Блэкбокс. Деталей уже не помню, но общий смысл в следующем. Компилятор думает, что внутри блока WITH после кастинга динамический тип переменной на которую ссылается закастованная ссылка на протяжении всего блока уже не изменяется. Но это не всегда так. Дело в том, что той переменной, на которую мы получили ссылку теперь можно присвоить другое значение (например, с помощью другого указателя) с другим динамическим типом. Так получается, что WITH - это дыра в системе защиты типов.
-
На Оберонкоре Трурль показывал как с помощью WITH завалить Блэкбокс. Деталей уже не помню, но общий смысл в следующем. Компилятор думает, что внутри блока WITH после кастинга динамический тип переменной на которую ссылается закастованная ссылка на протяжении всего блока уже не изменяется. Но это не всегда так. Дело в том, что той переменной, на которую мы получили ссылку теперь можно присвоить другое значение (например, с помощью другого указателя) с другим динамическим типом. Так получается, что WITH - это дыра в системе защиты типов.
Но, по моему, тот же финт ушами в GPCP не прокатывает и ничего там завалить не выйдет.
-
значит это хреновая охрана (реализация)... проблема реализации... видать разума на который надеялся Вирт, писавший 16 страничное сообщение об языке, не хватает у его учеников для нормальной реализации...
-
Умом Вирта и Ко не понять. Просрали практически идеальные условия для успеха Оберонов. Вместо того, чтобы отдать в массы ББ, сидят на своих глюках, ни миру ни себе.
-
но конечно понятно, что отследить возможное изменение довольно трудно... например, если в охране вызывается процедура юзающая оный указатель (изменение идет внутри нее), так что is и as вполне адекватны
-
выбор Вирта (между запрещением опасных процедур использующих охраняемую переменную и удалением невнятной конструкции) предсказуем...
-
Но, по моему, тот же финт ушами в GPCP не прокатывает и ничего там завалить не выйдет.
GPCP сэйфный и использует родное-дотнетное приведение типов, оно в 7 раз медленнее нативного оберонистого приведения типов. GPCP эмулирует оберонистые value-типы дотнетными ссылочными, то есть там где в обероне было бы размещение записи на стэке в GPCP будет размещение в динамической памяти. Короче, GPCP - это такое огромное недоразумение.
-
Но, по моему, тот же финт ушами в GPCP не прокатывает и ничего там завалить не выйдет.
GPCP сэйфный и использует родное-дотнетное приведение типов, оно в 7 раз медленнее нативного оберонистого приведения типов. GPCP эмулирует оберонистые value-типы дотнетными ссылочными, то есть там где в обероне было бы размещение записи на стэке в GPCP будет размещение в динамической памяти. Короче, GPCP - это такое огромное недоразумение.
Оно может конечно и недоразумение, но тут это вообще не к месту упомянуто. Я к тому, что там и рантайм-ошибку получить не удастся (например исключение).
PS. Вообще, эти 7 раз в куче приложений никогда не всплывут.
-
Оно может конечно и недоразумение, но тут это вообще не к месту упомянуто. Я к тому, что там и рантайм-ошибку получить не удастся (например исключение).
В смысле.. нельзя указатель загнать в процедуру и сделать там рекаст , или не дает это компилятор?
-
Умом Вирта и Ко не понять. Просрали практически идеальные условия для успеха Оберонов. Вместо того, чтобы отдать в массы ББ, сидят на своих глюках, ни миру ни себе.
:) Не они сидят(создатели), а коровцы - и им очень даже нравится это.
-
Оно может конечно и недоразумение, но тут это вообще не к месту упомянуто. Я к тому, что там и рантайм-ошибку получить не удастся (например исключение).
В смысле.. нельзя указатель загнать в процедуру и сделать там рекаст , или не дает это компилятор?
Если мне склероз не изменяет, оно не даст (на этапе компиляции просто не скомпилится) изменить то что накастил.
The semantics of the WITH statement have been slightly modified so as to strengthen
the guarantees on the properties of the selected variable. In the code —
WITH x : TypeTi DO
... (* guarded region *)
| x : TypeTj DO
... (* guarded region *)
END;
the variable x is asserted to have the specified type throughout the so-called guarded
region. The base language guarantees that the type of the selected variable cannot be
“widened” in the guarded region, but might possibly be narrowed. In gpcp the selected
variable is treated as a constant, and neither the type nor the value can be modified
either directly or indirectly. Any attempt to do so attracts a compile-time error message.
-
Не я говорю про другое
WITH A:childtype DO Dowithparent(A) ;
где Dowithparent обьявлена как PROCEDURE Dowithparent(VAR A:parenttype) ; -в ней идет рекаст аргумента несовместимый с охраняемым childtype
-
Не я говорю про другое
WITH A:childtype DO Dowithparent(A) ;
где Dowithparent обьявлена как PROCEDURE Dowithparent(VAR A:parenttype) ; -в ней идет рекаст аргумента несовместимый с охраняемым childtype
Что-то я под вечер туго соображаю. Дай пожалуйста полный код с тем самым рекастом.
-
Нет у австралийцев не прокатит "In gpcp the selected
variable is treated as a constant, and neither the type nor the value can be modified
either directly or indirectly. Any attempt to do so attracts a compile-time error message." выделенное я пропустил я пропустил впрочем это ясно и из "variable is treated as a constant"
-
то есть там работает это как надо... а уж насколько это эффективно реализовано... это другой вопрос.
-
Нет у австралийцев не прокатит "In gpcp the selected
variable is treated as a constant, and neither the type nor the value can be modified
either directly or indirectly. Any attempt to do so attracts a compile-time error message." выделенное я пропустил я пропустил впрочем это ясно и из "variable is treated as a constant"
Ну, я ж говорю что они коварные и радостно дырочку прикрыли. И пофик через какое место там каст делается - через механизмы .net/java или же быстрый нативный оберон-стайл каст.
-
я имел ввиду нечто вроде этого
MODULE mm;
IMPORT Log := StdLog, In := i21sysIn, Math;
TYPE
T0 = EXTENSIBLE RECORD x: INTEGER END;
T1 = RECORD (T0) y: REAL END;
T2 = RECORD (T0) z: INTEGER END;
P0=POINTER TO T0;
P1=POINTER TO T1;
P2=POINTER TO T2;
VAR p:P0; pp:P1;
PROCEDURE Do(VAR P:P0);
VAR pt:P2;
BEGIN
NEW(pt);
pt.z:=4;
P:=pt;
END Do;
BEGIN
NEW(pp);
p:=pp;
WITH p:P0 DO Do(p); END;
WITH p:P1 DO p.y:=4.5 END;
END mm.
прекрасно компилирующееся и выполняющееся в ББ
-
:) поправка - загрузка таки дает трап.
-
А вот аналог этого модуля не компилируется в XDS с ошибкой: control variable "p" is threatened here- что весьма логично. Нда- вспоминаются Инфо21 с компашкой и их восторги -воистину блаженны несведущие ;D
-
Нужно наверно просто запретить внутри WITH передавать охраняемый указатель VAR и OUT параметром. И ловить это на этапе компиляции.
-
Мне вот интересно другое.. является ли Вирт источником этой болячки (наличествует она в Виртовстких версиях Оберонов, или косолапость учеников).
-
Для тех кто не понял, что я написал вчера, вот код:
MODULE TestWith;
IMPORT Log;
TYPE
R0 = POINTER TO EXTENSIBLE RECORD END;
R1 = POINTER TO RECORD (R0) END;
R2 = POINTER TO RECORD (R0) END;
R3 = POINTER TO RECORD (R0) END;
VAR
globalPointer: R0;
PROCEDURE NewR1 (): R1;
VAR x: R1;
BEGIN NEW(x); RETURN x
END NewR1;
PROCEDURE NewR2 (): R2;
VAR x: R2;
BEGIN NEW(x); RETURN x
END NewR2;
PROCEDURE NewR3 (): R3;
VAR x: R3;
BEGIN NEW(x); RETURN x
END NewR3;
PROCEDURE Print (x: R0);
BEGIN
IF x IS R1 THEN Log.String("R1"); Log.Ln
ELSIF x IS R2 THEN Log.String("R2"); Log.Ln
ELSIF x IS R3 THEN Log.String("R3"); Log.Ln
END
END Print;
PROCEDURE f (VAR localPointer: R0);
BEGIN
WITH localPointer: R1 DO (* убедились, что localPointer стопудово указывает на R1 *)
Print(localPointer);
globalPointer := NewR2(); (* начиная с этого места localPointer тоже указывает на R2 *)
Print(localPointer);
globalPointer := NewR3(); (* начиная с этого места localPointer тоже указывает на R3 *)
Print(localPointer)
ELSE
END
END f;
PROCEDURE Do*;
BEGIN
globalPointer := NewR1();
f(globalPointer)
END Do;
END TestWith.
-
Охренеть. А ведь это никакой компилятор не отследит.
Мне начинает казаться, что Вирт прав...
-
То ли я сегодня торможу - но криминала в этом куске кода , Сергей, не вижу( не вижу изменения localPointer о котором вы говорите) - вы три раза печатаете один и тот же localPointer .
-
А вы попробуйте так:
...
TYPE
R1 = POINTER TO RECORD (R0) [b]a: INTEGER[/b] END;
R2 = POINTER TO RECORD (R0) [b]b: INTEGER[/b] END;
R3 = POINTER TO RECORD (R0) [b]c: INTEGER[/b] END;
...
ну и:
PROCEDURE f (VAR localPointer: R0);
BEGIN
WITH localPointer: R1 DO (* убедились, что localPointer стопудово указывает на R1 *)
Print(localPointer);
globalPointer := NewR2(); (* начиная с этого места localPointer тоже указывает на R2 *)
Print(localPointer); [b]Log.Int(localPointer.a);[/b]
globalPointer := NewR3(); (* начиная с этого места localPointer тоже указывает на R3 *)
Print(localPointer)
ELSE
END
END f;
-
И даже так не вижу этого изменения...
-
Глобал и локал поинтеры - это один и тот же поинтер.
Меняем глобал, следовательно меняется локал.
-
Теперь понял (не обратил внимание на способ передачи указателя в F)-спасибо, голова по пятницам вообще не работает :(
-
а если так , то ответ на вопрос "является ли Вирт источником этой болячки (наличествует она в Виртовстких версиях Оберонов, или косолапость учеников)." вполне очевиден.
-
Попробовал вот такой код:
MODULE TestWith;
IMPORT Log;
TYPE
R0 = POINTER TO EXTENSIBLE RECORD END;
R1 = POINTER TO RECORD (R0) a: ARRAY 100 OF CHAR END;
R2 = POINTER TO RECORD (R0) END;
R3 = POINTER TO RECORD (R0) END;
VAR
globalPointer: R0;
PROCEDURE NewR1 (): R1;
VAR x: R1;
BEGIN NEW(x); RETURN x
END NewR1;
PROCEDURE NewR2 (): R2;
VAR x: R2;
BEGIN NEW(x); RETURN x
END NewR2;
PROCEDURE NewR3 (): R3;
VAR x: R3;
BEGIN NEW(x); RETURN x
END NewR3;
PROCEDURE Print (x: R0);
BEGIN
IF x IS R1 THEN Log.String("R1"); Log.Ln
ELSIF x IS R2 THEN Log.String("R2"); Log.Ln
ELSIF x IS R3 THEN Log.String("R3"); Log.Ln
END
END Print;
PROCEDURE f (VAR localPointer: R0);
VAR
a: INTEGER;
BEGIN
WITH localPointer: R1 DO (* убедились, что localPointer стопудово указывает на R1 *)
Print(localPointer);
globalPointer := NewR2(); (* начиная с этого места localPointer тоже указывает на R2 *)
Print(localPointer); localPointer.a := "jsdfdfkjghdfkjgkjdfgjdkfhgkjdfhgkjdfghkjdfhgkjdfhgkjdfhgkjdhfgkjhdfkjghdfk";
globalPointer := NewR3(); (* начиная с этого места localPointer тоже указывает на R3 *)
Print(localPointer)
ELSE
END
END f;
PROCEDURE Do*;
BEGIN
globalPointer := NewR1();
f(globalPointer)
END Do;
END (^Q)TestWith.Do
ЧЯ то никак не реагирует, то падает без трапа, а иногда выдает бесконечную гирлянду траповых окошек, пока виндозным диспетчером не срубишь....
-
Охренеть. А ведь это никакой компилятор не отследит.
Мне начинает казаться, что Вирт прав...
;) не так все грустно
"In gpcp the selected
variable is treated as a constant, and neither the type nor the value can be modified
either directly or indirectly. Any attempt to do so attracts a compile-time error message." - правда как они умудряются сделать это -compile -time, мне лично не ясно.
-
А ведь это очень серьезная дырка в BB (да и в оригинальном Обероне наверно тоже). В безопасном языке, вполне законно можно засрать память!
Я кажется понял почему Вирт не комментирует причины удаления WITH. Вы представляете какой это позор?
-
А ведь это очень серьезная дырка в BB (да и в оригинальном Обероне наверно тоже). В безопасном языке, вполне законно можно засрать память!
Я кажется понял почему Вирт не комментирует причины удаления WITH. Вы представляете какой это позор?
Позор не Вирту - он гик и этим все сказано - глупо с него что либо трясти, позор коровцам - которые сделали из него идолище... сомневаюсь что Вирт просил их об этом.. нда а сколько "пафосных" речей о герметичности типов... о превосходстве Оберонов, о легкости создания компилятора.... по иронии судьбы единственная рабочая (надо проверить) реализация основана на "враждебной" платформе .net... как усерался Инфо21 охаивая ее... :(
-
Да, GPCP надо бы проверить... Сомневаюсь, что они смогли этот случай обойти.
-
По крайней мере, они четко поставили проблему - а это очень много... то есть занюханные австралийцы оказались умнее всемирно признанного мэтра и его школы... такие вот пироги...
За такие речи в коровнике предали бы чела отлучению?
-
Расстрел через повешение... не меньше ;)
-
Позор не Вирту - он гик и этим все сказано - глупо с него что либо трясти, позор коровцам - которые сделали из него идолище... сомневаюсь что Вирт просил их об этом.. нда а сколько "пафосных" речей о герметичности типов... о превосходстве Оберонов, о легкости создания компилятора.... по иронии судьбы единственная рабочая (надо проверить) реализация основана на "враждебной" платформе .net... как усерался Инфо21 охаивая ее... :(
Поправочка - jvm и .net.
-
нда... господа почему то мне , возможно, впервые за 2 года регулярного охаивания коровят... грустно, по настоящему грустно...
-
нда... осталось узнать , когда трурль обнаружил это говнецо ... - если года 2 назад... можно вполне серьезно обвинить эту секту в лицемерии, и целенаправленном одурачивании... альтернатива - не слаще .. - непроходимая тупость.
-
Я поискал там, но не нашел. Может уже цензура зарубила...?
-
И понятно, почему Оминк не вы..тся с ББ... им выгоднее это дело замять потихоньку..
-
А Вирт имхо правильно поступил. Доказать, что WITH безопасен будет довольно сложно. Значит удалить его нафик. Безопасность имеет больший приоритет, чем удобство.
-
С чего бы? все зависит области использования... мне вот например на нее начхать (если использовать обероны для образовательных нужд, там все предельно просто... полгода отрабатываешь навыки алгоритмизации на простейшем высокоуровневом ЯП, а далее переходишь на промышленные яп) -один черт придется переходить на что-то более близкое к реальности...
-
У меня просто еще теплится надежда, что он найдет свою нишу ;)
-
А ведь это очень серьезная дырка в BB (да и в оригинальном Обероне наверно тоже). В безопасном языке, вполне законно можно засрать память!
Я кажется понял почему Вирт не комментирует причины удаления WITH. Вы представляете какой это позор?
Не вздумайте сказать об этом оберонкоровам -- они вас заклюют! ;D
-
Охренеть. А ведь это никакой компилятор не отследит.
Мне начинает казаться, что Вирт прав...
Да нет никакой принципиальной дырки в WITH. Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами. Т.е., делать полноценную копию (и лучше даже с другим именем). Тогда не надо будет никаких специальный телодвижений в компиляторе. Я уже об этом говорил (не помню в личке с Ильей или на оборонкоре).
WITH p1: derived_p1: Derived1 DO
Где derived_p1 - локальная переменная с типом Derived1. С типом оригинальной переменной p1 ничего не происходит.
-
Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами.
А в качетстве дополнительного профита - станет возможным использовать полноценное выражение в качестве аргумента WITH:
WITH expression_p1(): derived_p1: Derived1 DO
-
Вообще сама идея, что одна и та же переменная в разных участках процедуры имеет разный тип - мягко говоря нездоровая (для статически типизированного ЯП).
-
Да нет никакой принципиальной дырки в WITH. Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами. Т.е., делать полноценную копию (и лучше даже с другим именем). Тогда не надо будет никаких специальный телодвижений в компиляторе. Я уже об этом говорил (не помню в личке с Ильей или на оборонкоре).
Гораздо проще прекратить треп про герметичность... как не соответствующий действительности - мне вот лично на нее начхать, тем кто использует ББ полагаю тоже... принципиальность этому вопросу придали коровцы... а те в свою очередь (боюсь ошибиться) - от статей учеников Вирта.
-
Вообще сама идея, что одна и та же переменная в разных участках процедуры имеет разный тип - мягко говоря нездоровая (для статически типизированного ЯП).
Естественно, но вопрос в другом - см. выше.
-
Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами.
Беда в том, что это юзанье вполне может быть и не явным - например, когда глобальный указатель и меняющие его тип процедуры определены в стороннем откомпилированном модуле - человек вызывающий эти процедуры может даже не знать о изменении фактического типа данных... просто вызывая в охране безобидную на вид документированную процедуру DoSomething() без параметров или с параметрами не относящимися напрямую к охраняемому указателю.
-
Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами.
Беда в том, что это юзанье вполне может быть и не явным - например, когда глобальный указатель и меняющие его тип процедуры определены в стороннем откомпилированном модуле - человек вызывающий эти процедуры может даже не знать о изменении фактического типа данных... просто вызывая в охране безобидную на вид документированную процедуру DoSomething() без параметров или с параметрами не относящимися напрямую к охраняемому указателю.
Если компилятор не будет реюзать переменную, то не важно, что делает DoSomething(). После каста в WITH на руках остается кастнутая ссылка (новая переменная) на оригинал. Так что с герметичностью все хорошо.
-
Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами.
Беда в том, что это юзанье вполне может быть и не явным - например, когда глобальный указатель и меняющие его тип процедуры определены в стороннем откомпилированном модуле - человек вызывающий эти процедуры может даже не знать о изменении фактического типа данных... просто вызывая в охране безобидную на вид документированную процедуру DoSomething() без параметров или с параметрами не относящимися напрямую к охраняемому указателю.
Если компилятор не будет реюзать переменную, то не важно, что делает DoSomething(). После каста в WITH на руках остается кастнутая ссылка (новая переменная) на оригинал. Так что с герметичностью все хорошо.
Ну нет, так не пойдет... компилятор ДОЛЖЕН юзать то что ему пропишет программист руководствуясь алгоритмом.. а в языке четко прописан смысл понятий- глобальная переменная, и передача параметра по ссылке- я это к тому, что соответствующее изменение необходимо вносить в первую очередь в ЯП. Но даже в этом случае это не есть самое простое решение.. ;) :D ;D вот Вирт, например, просто взял и удалил WITH из ЯП.... Ну как хорошо то - вы можете назвать с ходу реализацию от отцов- основателей языка свободную от этого недостатка (конечно, возможен такой вариант - им по барабану была герметичность раздутая до абсолюта некоторыми коровцами)?
-
vlad, вы меня опередили :D
Мне вчера в голову пришла та же мысль. Для реализации безопасного WITH необходимо и достаточно делать копию указателя после проверки типа.
Внутри блока все разыменования должны происходить с копией указателя.
В конце блока можно по вкусу делать проверку на равенство типов у исходного указателя и копии. Либо проверять равенство указателей, т.к. исходный мог косвенно измениться. Это уже вопрос семантики WITH.
А можно еще запретить внутри блока явные присваивания охраняемому указателю(т.е. копии) и не делать никаких проверок в конце. Если исходный указатель косвенно изменился, ну и шут с ним. Это уже вопрос соглашений.
-
Уточнение:
Все мной сказанное конечно должен делать компилятор а не программист ;)
-
Кстати, можно пойти другим путем. Например как я уже говорил запретить передавать охраняемый указатель VAR и OUT параметром. Плюс везде запретить передавать глобальные переменные VAR параметром. Т.е. тут вопрос правильной расстановки запретов. Конечно тут доказать правильность посложнее, но если нужна максимальная эффективность, то почему бы и нет.
И я согласен с вами DIzer и vlad, проблема то большей частью в том, у кого откуда руки растут. :)
Но ради справедливости хочу заметить, что в описании языка семантика WITH должна быть очень точно описана. Тогда разработчика можно ткнуть носом... чегой мол твоя реализация прописанную семантику не обеспечивает.
p.s. Если философски на все это посмотреть, то проблемы WITH отражают проблемы языка WIRTH'а вообще ;D
-
vlad, вы меня опередили :D
Мне вчера в голову пришла та же мысль. Для реализации безопасного WITH необходимо и достаточно делать копию указателя после проверки типа.
Внутри блока все разыменования должны происходить с копией указателя.
В конце блока можно по вкусу делать проверку на равенство типов у исходного указателя и копии. Либо проверять равенство указателей, т.к. исходный мог косвенно измениться. Это уже вопрос семантики WITH.
А можно еще запретить внутри блока явные присваивания охраняемому указателю(т.е. копии) и не делать никаких проверок в конце. Если исходный указатель косвенно изменился, ну и шут с ним. Это уже вопрос соглашений.
Это понятно.. но я говорю про другое... - вопрос о такой интерпретации ДОЛЖЕН быть декларирован языком... ибо принципиально он допускает работу с глобальными переменными- а это значит, что ЛЮБОЕ изменение делается с непосредственно с соответствующей ячейкой памяти - а тут на время выполнения охраняемой последовательности это правило нарушается... к чему это может привести я не хочу обсуждать - сейчас Оберон позиционируется как примитивный язык общего назначения смусорозборником -(ко всем дополнительным "достоинствам" его расписываемым коровцами у меня веры нет, как впрочем и к ним самим), из этого следует, что формальная( именно формальная) область его использования ничем не ограничена.
-
Дело в том, что семантически внутри WITH изменение типа охраняемого указателя невозможно по определению:
Оператор WITH выполняет операторную последовательность в зависимости от результата проверки типа и применяет охрану типа к каждому вхождению проверяемой переменной внутри операторной последовательности.
http://www.inr.ac.ru/~info21/cpascal/cp_report_1.4_rus.htm#9.11 (http://www.inr.ac.ru/~info21/cpascal/cp_report_1.4_rus.htm#9.11)
Следовательно той же семантикой запрещено и косвенное изменение типа. Т.е. должно быть исключение времени выполнения.
На входе в WITH и на выходе из него тип должен быть одним и тем же. Как это реализовано дело десятое...
-
А вот этого мы и не наблюдаем... по этому и есть несоответствие определению в существующих реализациях... что бы там Влад не говорил, а если сделать так как предлагает Влад - то это будет немного другой язык - правило о котором я говорил (одно из фундаментальных правил всех императивных языков) выше будет нарушаться . Естественно , я не говорю что оно плохое.. просто оно меняет язык и потенциально влияет на алгоритмы решения задач (ее отсутствие не является недостатком существующих реализаций компиляторов)
-
плохое - в смысле предложение Влада.. мне оно нравиться
-
хотя повторюсь.. я лично УВЕРЕН на 100%, что не заметил бы этой проблемы в своих приложениях даже с текущей реализацией KП.
-
Да нет никакой принципиальной дырки в WITH. Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами. Т.е., делать полноценную копию (и лучше даже с другим именем). Тогда не надо будет никаких специальный телодвижений в компиляторе. Я уже об этом говорил (не помню в личке с Ильей или на оборонкоре).
WITH p1: derived_p1: Derived1 DO
Где derived_p1 - локальная переменная с типом Derived1. С типом оригинальной переменной p1 ничего не происходит.
Гм. Я не уверен что эта модификация органично впишется в весь язык. Перепиши ка вот этот кусок кода:
(* Language: Oberon
WithStatement = WITH qualident ":" qualident DO StatementSequence END *)
TYPE
R0 = RECOR bar : INTEGER END
R1 = RECORD (R0) foo : INTEGER END
PROCEDURE Foo(VAR x : R0);
BEGIN
WITH x : R1 DO
x.foo := 42;
END
END Foo
PROCEDURE Test;
VAR
x : R1
BEGIN
Foo(x);
END Test
Как понимаешь, никаких указателей тут не фигурирует.
-
хотя повторюсь.. я лично УВЕРЕН на 100%, что не заметил бы этой проблемы в своих приложениях даже с текущей реализацией KП.
Аналогично
-
:( Вот... поползли контрпримеры... на этом пример... можно сказать - давайте задекларируем создание локальной копии любой охраняемой переменной (не только указателя).... в свою очередь всегда можно привести пример такой записи, что создание локальной копии ее будет неприемлемо из чисто практических соображений... другой выход.. разрешить WITH только с указателями...
-
...сделать так как предлагает Влад - то это будет немного другой язык...
Полностью согласен.
-
Хотя конечно это дело можно развить и обобщить до внутренних блоков внутри функции со своими локальными переменными, часть которых являются производными от переменных основной функции после прохождения проверки на предусловие (по типу, значениям). По сути это дело отличается семантически от обычной вложенной функции только невозможностью рекурсии (то есть по умолчанию компилятор может спокойно это дело всегда инлайнить).
Но, по моему, я только что изобрел паттерн-матчинг в обероне :-)
Я кажется понял почему Вирт это дело выпилил - удобств особых это не добавляет, а язык сильно усложняет и запутывает. А поскольку WITH в Обероне никоем образом не похож на CASE, то даже обработку/разбор сообщений (в Message Bus) оно совсем не облегчает, соответственно Вирт просто избавился от бесполезного и не безопасного излишества.
-
WITH p1: derived_p1: Derived1 DO
Где derived_p1 - локальная переменная с типом Derived1. С типом оригинальной переменной p1 ничего не происходит.
Да, кстати. Уточню свою позицию:
Я думаю синтаксис WITH можно оставить как есть, а копию должен делать компилятор. Т.е. это должно быть скрыто от программиста. Для него это тот же самый указатель.
В синтаксисе мне нравится предложение DIzer'а
-
valexey, а как такое писать?
http://oberspace.dyndns.org/index.php/topic,229.msg5264.html#msg5264 (http://oberspace.dyndns.org/index.php/topic,229.msg5264.html#msg5264)
-
как как... каст при каждом использовании ... аналог Дельфийского (TControl as Tbutton).visible:=true
-
точнее аналог следующий if ctrl is TButton then begin ... (ctrl as TButton) .visible:=true;.... end;
-
Неудобно ведь... Впрочем это ИМХО...
-
Неудобно ведь... Впрочем это ИМХО...
Тык вся философия Оберонов, в том, что не удобствах счастье... ;) :D ;D и Вирт следует ей бескомпромиссно и безжалостно к программисту...
-
гораздо более у него сочувствия к компилятороклепалам... (с чего бы это?)
-
Как понимаешь, никаких указателей тут не фигурирует.
Ну так и будет, если не указатель, то ссылка.
PROCEDURE Foo(VAR x : R0);
BEGIN
WITH x VAR r1: R1 DO
r1.foo := 42;
END
END Foo
-
Как понимаешь, никаких указателей тут не фигурирует.
Ну так и будет, если не указатель, то ссылка.
PROCEDURE Foo(VAR x : R0);
BEGIN
WITH x VAR r1: R1 DO
r1.foo := 42;
END
END Foo
А зачем такие сложности? Тогда уж сразу разрешить делать так:
PROCEDURE A(VAR x : R1);
BEGIN
x.foo := 42
END A
PROCEDURE B(VAR x : R0);
PROCEDURE BA(VAR x : R1); BEGIN x.foo = 24 END BA
BEGIN
A(x)
BA(x)
END B
PROCEDURE C;
VAR
x : R1;
BEGIN
B(x)
END C
-
А зачем такие сложности? Тогда уж сразу разрешить делать так:
Не, просто через процедуры неприкольно. Ошибок компиляции будет меньше, а багов больше ;)
-
А зачем такие сложности? Тогда уж сразу разрешить делать так:
Не, просто через процедуры неприкольно. Ошибок компиляции будет меньше, а багов больше ;)
Кстати, все таки украдено до нас. Go:
switch i := x.(type) {
case nil:
printString("x is nil")
case int:
printInt(i) // i is an int
case float64:
printFloat64(i) // i is a float64
case func(int) float64:
printFunction(i) // i is a function
case bool, string:
printString("type is bool or string") // i is an interface{}
default:
printString("don't know the type")
}
Таким образом у них switch может и типы перебирать и значения:
switch tag {
default: s3()
case 0, 1, 2, 3: s1()
case 4, 5, 6, 7: s2()
}
Одна конструкция вместо двух и отсутствие дырки которая была в Оберонах начиная с самого первого Оберона.
-
Круто! Прям по методу vlad'а
-
Жаль только в Оберонах нельзя определять переменные по месту, с областью действия только в данном блоке. Т.е. такая конструкция будет неудобна, т.к. придется VAR засирать вспомогательными переменными
-
Жаль только в Оберонах нельзя определять переменные по месту, с областью действия только в данном блоке. Т.е. такая конструкция будет неудобна, т.к. придется VAR засирать вспомогательными переменными
Ну есть еще вложенные процедуры…
-
Только их инлайнить нет возможности ;)
-
Только их инлайнить нет возможности ;)
В смысле? Ты про оптимизацию компиляторную, или же про что-то иное?
В плане оптимизации - можно.
-
В том смысле, что в языке это не предусмотрено. В CP я например не могу указать, что данную процедуру нужно инлайнить.
-
...А поскольку WITH в Обероне никоем образом не похож на CASE, то даже обработку/разбор сообщений (в Message Bus) оно совсем не облегчает...
Хочу просто уточнить:
Это про оригинальный Оберон?
-
...А поскольку WITH в Обероне никоем образом не похож на CASE, то даже обработку/разбор сообщений (в Message Bus) оно совсем не облегчает...
Хочу просто уточнить:
Это про оригинальный Оберон?
Да.
-
В том смысле, что в языке это не предусмотрено. В CP я например не могу указать, что данную процедуру нужно инлайнить.
В яве этого тоже не предусматривается, да и в Go тоже. И дофига где еще. И это все не мешает компилятору процедуры/функции инлайнить :-)
-
В середине обсуждения замечена типичная реакция известной аудитории - с потоками... удобрений... на поля :)
С последующим признанием, что никто из них 100% никогда не вляпался бы в эту проблему...
Выявленный случайно за годы использования дефект vs. тем, что я читаю через день в окне обновлений Ubuntu с названиями "Критическое обновление безопасности...". Сегодня меня предупредили, что для моей версии (10.10) обновлений безопасности больше не будет. И где позор?
Теперь по существу вопроса. Есть два понятия в сфере критических систем - safety (безопасность) и security (защищённость). Кроме них, ещё два - работоспособность и безотказность. За подробностями - к любой классике программной инженерии, например, Соммервиллу.
Safe-система - которая при штатных условиях применения не способна причинить вред. Безопасной бритвой невозможно причинить себе существенный вред при бритье. Но вполне можно убить человека, если выломать лезвие.
Security - это устойчивость системы к преднамеренным вредоносным действиям злоумышленника.
Да, в области языков программирования есть значительная связь между безопасностью и защищённостью.
Она связана с тем, что небезопасность языка провоцирует такие ошибки в программе, которые делают возможной её уязвимость извне - передачей специально подобранных данных. Либо сетевая уязвимость, либо межпроцессная (например, возможность вредоносного воздействия на код в нулевом кольце защиты). Пресловутые атаки на переполнение буфера. С точки зрения такой уязвимости обсуждаемый вопрос проблемы не порождает.
Всего лишь есть гипотетическая вероятность написать такой код, который приведёт к отказу. Как и при неправильном использовании SYSTEM. Оценки безопасности не делаются так же, как защищённости. В защищённости логика бинарная - либо есть уязвимость, либо нет. Потому что если есть, то она будет использована. В безопасности оценка вероятностная. Если вероятность случайно вляпаться пренебрежимо мала (и, тем более, на практике никогда не встречалась), то это не является претензией к safety. И не оказывает никакого влияния на работоспособность-безотказность.
Есть другое поле для обсуждения - вопрос компонентного программирования. Здесь safety языка, начиная с работ Вирта, рассматривается как гарантия невозможности разрушительного влияния одного компонента на другой. Тут мы подходим к интересному вопросу - влияния непроизвольного (из-за ошибки) или преднамеренного? С точки зрения непроизвольных влияний всё ясно - была убедительно показана безопасность языка и её преимущества для компонентного программирования.
С точки зрения преднамеренного. На мой взгляд, преждевременно были сделаны выводы о том, что safe-язык отменяет необходимость традиционных механизмов защиты ОС. Эти заключения вывода Вирта и учеников были потом повторены компанией Sun, которая связала safety и security внутри одного пространства памяти, куда "запускается" произвольный пришедший из недоверенного источника компонент. Как известно, много лет спустя были обнаружены уязвимости в их байт-коде, точно так же, как уязвимость через наш WITH.
На самом деле, про security внутри общего пространства памяти стоит забыть. Как минимум, потому, что security включает в себя не только невозможность разрушения системы, но и невозможность несанкционированного доступа к данными. Когда у нас есть единый граф связей, и "всё всюду гуляет", придумать механизмы контроля доступа - это безумно усложнить язык и/или библиотеки и/или рантайм. Поэтому, в сравнении с традиционными механизмами межпроцессной защиты такие попытки "идут лесом".
Просто традионная ОС "Оберон" была однопользовательской локальной. Индивидуальным инструментом. Поэтому ряд вопросов был оставлен за бортом, чтобы сконцентрироваться на других.
Это оправдано и по сей день, если в систему не приходят компоненты из недоверенных источников. Например, если это встроенная система. С серверной системой всё уже не так просто, если мы хотим позволить третьим лицам исполнять на нашей стороне что-нибудь. В частности, в том числе и поэтому я посчитал нецелесообразным опираться в сетевых проектах на ОС A2. В ней нет межпроцессной защиты. Которую я имею, гоняя Блэкбоксы на Линуксе.
Я рассматривал этот вопрос ещё больше года назад в статье в "Объектных системах".
http://ermakov.net.ru/pub/EIE-21-2010.pdf
Однако, как всегда, имеется и оборотная сторона медали: размываются границы между зонами ответственности отдельных приложений, затрудняется выгрузка и перезапуск отдельных компонентов (из-за плотной интеграции в «паутину» указателей). Наконец, практически невозможно обеспечить контроль прав компонентов и защиту от злонамеренных действий, либо это ведёт к такому усложнению языка и объектной системы, которое выходит за всякие рамки инженерной целесообразности. Таким образом, наличие раздельных объектных пространств остаётся востребованным для современных систем, за исключением некоторых применений (например, встраиваемых, мультимедийных — как раз тех, в нишу которых направлена ОС А2).
Конечно, проще драть глотку, чем серьёзно и непредвзято разбираться в вопросе.
-
Теперь по существу вопроса. Есть два понятия в сфере критических систем - safety (безопасность) и security (защищённость). Кроме них, ещё два - работоспособность и безотказность. За подробностями - к любой классике программной инженерии, например, Соммервиллу.
Ну-ну... С точки зрения теории систем... есть понятия устойчивости и надёжности системы. Устойчивость (динамических) системы можно рассматривать в "математическом" виде (например, по Ляпунову), а можно в более широком "физическом" виде (а-ля, шарик в чаше). Если говорить о программных системах, то... ничего не меняется, устойчивая программная система должна возвращаться в исходное состояние, если любые внешние или внутренние возмущения находятся в заданных ограничениях/пределах.
Надёжность системы - это её способность выполнять заданные функции. Надёжность характеризуется целым рядом показателей: безотказность, ремонтопригодность, сохраняемость, долговечность... Приоритет тех или иных показателей зависит от многих факторов и определяется до начала проектирования системы. Надёжность системы определяется наиболее слабым её элементом. Это фактор является ключевым при проектировании систем.
Всё сказанное - "манная каша"... то, что должен знать любой человек, который хочет заниматься системами: созданием, эксплуатацией, обслуживанием. А для того, кто уже занимается системами... обсуждать это как-то... странно. Тем не менее, западная литература по программированию постоянно преподносит новые "открытия", которые потом тиражируются восторженными адептами... (Как это у классика: "Кричали женщины: "Ура". И в воздух чепчики бросали").
Safe-система - которая при штатных условиях применения не способна причинить вред. Безопасной бритвой невозможно причинить себе существенный вред при бритье. Но вполне можно убить человека, если выломать лезвие.
Кому не способна причинить вред? Себе или внешней среде?.. Что в приведённом примере рассматривается как система? Бритва или человек, который бреется?..
Security - это устойчивость системы к преднамеренным вредоносным действиям злоумышленника.
А непреднамеренным?.. Границу между "преднамеренным" и "непреднамеренным" провести можно?.. "Вредоносность" чем меряется?.. И про "злоумышленника"... тоже интересно... в контексте устойчивости систем в агрессивной среде...
Да, в области языков программирования есть значительная связь между безопасностью и защищённостью.
Она связана с тем, что небезопасность языка провоцирует такие ошибки в программе, которые делают возможной её уязвимость извне - передачей специально подобранных данных. Либо сетевая уязвимость, либо межпроцессная (например, возможность вредоносного воздействия на код в нулевом кольце защиты).
Это напоминает... "правила затачивания карандашей при проектировании космического корабля"... No comments...
Конечно, проще драть глотку, чем серьёзно и непредвзято разбираться в вопросе.
Точно помечено... Так сказать... "не бровь, а в глаз"...
PS. С праздником всех!
-
В середине обсуждения замечена типичная реакция известной аудитории - с потоками... удобрений... на поля :)
С последующим признанием, что никто из них 100% никогда не вляпался бы в эту проблему...
(тут много букф)
...Конечно, проще драть глотку, чем серьёзно и непредвзято разбираться в вопросе.
А на мой взгляд получился нормальный диалог. :)
Эмоции.... конечно они есть. Ведь порча памяти это совсем не то, что ожидаешь от Оберона в подобной ситуации.
Далее vlad'ом было указано как можно сделать WITH безопасным. А DIzer указал, что это проблема по большей части реализации, а не языка. И я указал, что семантику нужно более точно определять.
И все это было "серьёзно и непредвзято". ;)
-
Да, идею Влада про WITH я помню ещё со времён, когда он мне её писал. Хорошая идея, на мой взгляд.
Alexus, как часто у него бывает, поднялся в заоблачные выси и замутил предельно простую суть, что устойчивость к преднамеренной атаке и устойчивость к случайным ошибкам - принципиально разные вещи. В отсутствие злоумышленника, например, дверь не нуждается в замке - и может быть совершенно надёжным устройством в его отсутствие.
-
Да, идею Влада про WITH я помню ещё со времён, когда он мне её писал. Хорошая идея, на мой взгляд.
Но возникают проблемы с дизайном при попытке внедрения в Оберон. Собственно было показано какие проблемы и было показано в каком языке это было успещно введено и почему там проблем не возникло.
В общем, весьма вменяемое, продуктивное обсуждение.
-
Да, идею Влада про WITH я помню ещё со времён, когда он мне её писал. Хорошая идея, на мой взгляд.
Alexus, как часто у него бывает, поднялся в заоблачные выси и замутил предельно простую суть, что устойчивость к преднамеренной атаке и устойчивость к случайным ошибкам - принципиально разные вещи.
Как я понимаю, ползающий по низине Илья, сейчас нам расскажет, чем одна устойчивость отличается от другой устойчивости... с примерами и... теоретическими изысками. Право стыдно, рассуждать о системах... не имея представления об оных.
В отсутствие злоумышленника, например, дверь не нуждается в замке - и может быть совершенно надёжным устройством в его отсутствие.
Дверь - это система? Или система - это квартира/дом?.. Дверь может быть надёжной, даже будучи тряпичной занавеской... является ли при этом надёжной квартира/дом?.. В какой среде данная система (дверь/квартира/дом) может считаться надёжной?.. Является ли сохранение имущества функцией данной системы в данной среде?.. И, наконец, хотелось бы знать более точные сведения о том, кто является злоумышленником?... Болтливая соседка, например... относится к данной категории или нет?..
(Илья, я же понимаю, что начитавшись очередных высказываний очередных проповедников, при полном нежелании думать... будем писать чушь, с видом оскорблённой невинности... ну, да и пишите... не обращайте на меня внимания... помните, что Эйнштейн писал по поводу Вселенной и глупости... не сдерживайте себя... границ нет... пишите...)
-
В середине обсуждения замечена типичная реакция известной аудитории - с потоками... удобрений... на поля :)
С последующим признанием, что никто из них 100% никогда не вляпался бы в эту проблему...
Выявленный случайно за годы использования дефект vs. тем, что я читаю через день в окне обновлений Ubuntu с названиями "Критическое обновление безопасности...". Сегодня меня предупредили, что для моей версии (10.10) обновлений безопасности больше не будет. И где позор?
Так если вам перепадают "удобрения" ростерите и расцветайте... вы же пока "отсекаете" ветки... - лично я вижу уродливый "кактус" и горстку "впопуасов" танцующих вокруг него... Позора - о котором говорит ilovb (в отношение Вирта) - лично я не вижу... но в убогости вашей "компашки" лично я - не сомневаюсь... высказывание как Ваши так и Инфо21 я помню - и мне пофиг подчищаете вы дерьмо за СОБОЙ на форуме, или нет....
-
Есть конкретный вопрос: является ли некоторый дефект дизайна языка критическим.
На него есть два принципиально разных ответа, в зависимости от того, рассматриваем ли мы аспект защищённости от умышленных действий по нарушению работы программного процесса (я понял, что слово "система" в присутствие alexus-а лучше вообще не употреблять, ибо при виде слова "система" он тут же выведет разговор на заоблачные для обсуждаемой темымета-уровни) или аспект безопасности - невозможности поиметь проблемы от данного дефекта при отсутствии вредоносного кода внутри процесса.
Условный, не совсем аналогичный пример. Например, у бронестекла есть точка концентрации напряжений. Вероятность попадания в эту точку невысока. Очевидно, что если никто не знает, где данная точка (не имеет возможности целенаправленно в неё бить), то наше стекло можно считать довольно надёжной защитой. Если же информация о месте этой точки известна стрелку, то стекло вообще перестаёт быть защитой.
Т.е. граница между преднамеренными и непреднамеренными воздействиями очень отчётливая. И никакая их общность на метауровне не отменяет этой границы.
Не стыдно, залезая в неуместную в обсуждаемой теме софистику, потом пытаться выставлять своих собеседников идиотами?
-
Право стыдно, рассуждать о системах... не имея представления об оных.
Хорошо, я заменяю слово "система" в вышенаписанном тексте на "программное приложение/процесс" (в зависимости от контекста). Собственно, это и так было очевидно.
Таким образом, ни на какие рассуждения о Системах я не претендую в данной ветке.
-
Право стыдно, рассуждать о системах... не имея представления об оных.
Хорошо, я заменяю слово "система" в вышенаписанном тексте на "программное приложение/процесс" (в зависимости от контекста). Собственно, это и так было очевидно.
Таким образом, ни на какие рассуждения о Системах я не претендую в данной ветке.
Остаётся только удивляться... Что останется в первом сообщении (http://oberspace.dyndns.org/index.php/topic,229.msg5466.html#msg5466), если из этого сообщения выбросить рассуждения о системах?..
С другой стороны, я не удивлён... "свободное" использование любых терминов... стало очень распространено. Думать уже не надо, просто набрасываешь "наукообразных" слов... Ляпота... (не путать с лепотой).
-
...граница между преднамеренными и непреднамеренными воздействиями очень отчётливая...
Это ваш теоретический вывод. А вот в армии например есть практический вывод, который очень хорошо выражен в пословице: "Раз в год и палка стреляет"
http://www.huntingsib.ru/news/view/28179/ (http://www.huntingsib.ru/news/view/28179/)
...
Но судья Зайцев сам был не чужд риторики. «Вы когда-нибудь служили в армии? Про несчастные случаи из-за неосторожного обращения с оружием слышали? А на охоту не ходили? Простреленных «уазиков» не видели? -- спрашивал судья у любителя оружия, а тот в ответ отрицательно качал головой. -- А был случай, когда один охотник другого на себе тащил, но так и не дотащил, потому что кто-то забыл ружье разрядить. Давайте классику вспомним: если в первом акте пьесы на стене висит ружье, то в последнем оно обязательно выстрелит. А еще говорят, что раз в год и палка стреляет». «Вот поэтому я свое ружье регулярно на стрельбище выгуливаю!» -- не растерялся с ответом г-н Леуш.
...
«Все, кто связан с оружием и охотой, понимают, что правила по его хранению прописаны кровью, -- констатировал он. -- Оружие создано для поражения живых людей и животных, и слишком много безопасности в обращении с ним быть не может». И с этим утверждением спорить было сложно. В результате судья Зайцев в удовлетворении заявления Андрея Леуша отказал.
-
Есть совершенно очевидный факт, что всего случаев "стреляния" обсуждаемого средства может быть если не 0, то 1 или 2... За всю историю существования у всех применявших и будущих применять в ближайшие годы :)
Остальное про палки - тень на плетень.
Если господам не хочется видеть очевидные вещи - что поделать.
Я-то наивно что-то попытался объяснить о реальных проблемах с защищённостью и что их не перекрыть без традиционных средств ОС, одним safe-языком, даже таким, как Оберон :)
Опять всё потонуло в каких-то криках.
Замечательный форум :)
-
.....
Т.е. граница между преднамеренными и непреднамеренными воздействиями очень отчётливая. И никакая их общность на метауровне не отменяет этой границы.
Не стыдно, залезая в неуместную в обсуждаемой теме софистику, потом пытаться выставлять своих собеседников идиотами?
Ну да, есть немного ...загнул... конечно ... впопуасы и кактус... фи.. правильнее -- впопуасы и идолище... В ответ... Илья а не стыдно паразитировать на Вирте и ББ - от которого отказались сами создатели..., забивать мозги аудитории болтовней -поясню ВЫ создали эту проблему - когда развили возню по поводу герметичности типов... , надежности, простоты реализации компилятора... да согласен Ваша болтовня, безусловно , не является критической - но это здесь, а в коровнике до сих пор орудуют Ваши эцилопы...
-
Я-то наивно что-то попытался объяснить о реальных проблемах с защищённостью и что их не перекрыть без традиционных средств ОС, одним safe-языком, даже таким, как Оберон :)
А что/зачем/кому о безопасности вообще вы "наивно пытались" объяснить? Когда речь в этой ветке идет о конкретном языке, и о возможности порчи памяти в нем... ;)
А у DIzer'а вполне обоснованная претензия так как:
...безопасный язык программирования гарантирует целостность памяти...
http://oberoncore.ru/library/pfister_component_software4 (http://oberoncore.ru/library/pfister_component_software4)
-
Остальное про палки - тень на плетень.
Чуйствуется пренебрежительное отношение к армейской пословице :)
Вы с ней не согласны?
-
А у DIzer'а вполне обоснованная претензия так как:
...безопасный язык программирования гарантирует целостность памяти...
http://oberoncore.ru/library/pfister_component_software4 (http://oberoncore.ru/library/pfister_component_software4)
Нет - смысл моей претензии в другом.. в том, что они именем идола -творили непотребности ЗНАЯ о дефектности.
-
Остальное про палки - тень на плетень.
Чуйствуется пренебрежительное отношение к армейской пословице :)
Вы с ней не согласны?
Не пословицей они пренебрегают... людьми - приматами (но это в коровнике естественно :D).
-
2 DIzer.
Я просто привел цитату с оберкора, в подтверждение источника утверждений о безопасности.
А стимулом к цитированию было это ваше сообщение:
Гораздо проще прекратить треп про герметичность... как не соответствующий действительности - мне вот лично на нее начхать, тем кто использует ББ полагаю тоже... принципиальность этому вопросу придали коровцы... а те в свою очередь (боюсь ошибиться) - от статей учеников Вирта.
Контекст в моей голове короче остался :)
-
Я просто привел цитату с оберкора, в подтверждение источника утверждений о безопасности.
Боюсь, вы привели пример паскудства коровцев - когда догма делается из личных соображений автора работы - такие вещи нормальные авторы не любят - хе коровцы достаточно многим задолжали, однако..., хотя ученики Вирта "кровососы" еще те.... - так им и надо! (ИМХО).
-
хотя ученики Вирта "кровососы" еще те.... - так им и надо! (ИМХО).
кровосиси, как сказал Азаров:)
-
Я-то наивно что-то попытался объяснить
А ты попробуй ещё раз, а то мы не поняли (ты написал слишком много букв).
???
-
Илья а не стыдно паразитировать на Вирте и ББ - от которого отказались сами создатели..., забивать мозги аудитории болтовней -поясню ВЫ создали эту проблему - когда развили возню по поводу герметичности типов... , надежности, простоты реализации компилятора...
Что не так с герметичностью типов, кроме единственного обнаруженного дефекта, который, как мы выяснили, не снижает safety языка? У нас что-то есть более герметичное (не такое же, а более)? Существовало что-то такое же герметичное раньше Оберонов? Если учитывать многолетние рекламные крики про Java о безопасности именно уровня "полной песочницы" и последующие обнаруженные в байткоде уязвимости, то счёт даже не 1:1... а немного не в пользу Java. Потому что уверенных утверждений о "полной песочнице" для Оберонов особо не делалось. Я, например, таковыми идеями (защита на языковом уровне от потенциально вредоносных компонентов) не увлекался вообще.
Что не так с надёжностью, у системы, которая работает у меня с 2005 г. каждый день и ни разу не упала без моей порчи памяти (возня на низком уровне или проч.)?
Что не так с простотой, наконец?
Есть реальность - где есть штука, которая хорошо работает. И есть какая-то вечная софистика вокруг этой реальности. Где уже возникла, например, какая-то мнимая проблема "негерметичности" и т.п. Где коллега ivovb, которому в РЕАЛЬНОМ проекте никогда не пришло бы в голову придавать значение этой "уязвимости", начинает разводить какие-то словеса о "ружье". Форум стерпит любую болтовню - но только вот вопрос: форум нам нужен как инструмент для обсуждения реальных вещей или как площадка для игры в слова?
-
А что/зачем/кому о безопасности вообще вы "наивно пытались" объяснить? Когда речь в этой ветке идет о конкретном языке, и о возможности порчи памяти в нем... ;)
В отсутствие вредоносных компонентов в пространстве памяти приложения вероятность совершения программистом ошибки с WITH, которая может вызвать порчу памяти, пренебрежимо мала. Вероятность совершения ошибки программистом, а не вероятность порчи памяти в работающем приложении, которая ещё меньше. Поэтому данный дефект не снижает safety языка, с точки зрения инженера, а не софиста.
Для security, если мы расчитывали его обеспечивать для компонентов, урон от данного WITH сокрушительный, поскольку кто угодно может целенаправленно обрушить наше приложение.
Вот что я пытался здесь донести. Кто хочет прочитать, тот прочитает. Всего наилучшего.
-
Нет - смысл моей претензии в другом.. в том, что они именем идола -творили непотребности ЗНАЯ о дефектности.
В 2005 г., в момент перевода данной статьи, не было известно о дефекте никому из сообщества, мне известного.
Кстати, идите покричите Sun-у (Ораклу), которая ПРОДАВАЛА "безопасную песочницу", в модели байт-кода которой потом университетские исследователи находили фатальные дыры.
-
...урон от данного WITH сокрушительный
В данной конкретной реализации, потому что сама по себе конструкция WITH вполне адекватная, а реализовать полностью безопасный механизм не так уж и сложно и оверхед небольшой будет, вполне терпимый, проявляющийся только при lvalue.
-
Где коллега ilovb, которому в РЕАЛЬНОМ проекте никогда не пришло бы в голову придавать значение этой "уязвимости", начинает разводить какие-то словеса о "ружье". Форум стерпит любую болтовню - но только вот вопрос: форум нам нужен как инструмент для обсуждения реальных вещей или как площадка для игры в слова?
Илья, посмотрите внимательно что я комментировал словесами о "ружье". Это была критика вашего утверждения об "отчетливой границе".
-
Не понимаю я это дурацкое выражение "герметичная система типов".
Герметичная ёмкость, в которой можно хранить воду без опасения что она вытечет -- это мне понятно.
Строгая типизация, слабая типизация и т. д. -- тоже понятно.
Но что за херня с этой вашей "герметичной системой типов"??? :o
Понавыдумывали левой терминологии, теоретики хреновы...
-
В отсутствие вредоносных компонентов в пространстве памяти приложения вероятность совершения программистом ошибки с WITH, которая может вызвать порчу памяти, пренебрежимо мала. Вероятность совершения ошибки программистом, а не вероятность порчи памяти в работающем приложении, которая ещё меньше. Поэтому данный дефект не снижает safety языка, с точки зрения инженера, а не софиста.
Во первых слова типа "пренебрежимо мала" ни чем не подкреплены.
Во вторых единственный софист в данной ветке - это вы. На сколько мне известно вы не являетесь специалистом в вопросах безопасности, и тем не менее "вещаете истину" без всяких "ИМХО". Я на это уже намекнул пословицей, но вы отмахнулись.
-
Вот что я пытался здесь донести. Кто хочет прочитать, тот прочитает. Всего наилучшего.
Илья, а тебе не надоело постоянно ругаться с людьми? Враждовать? Вещать истину? Особенно из-за такого пустяка как Оберон? :)
-
В данной конкретной реализации, потому что сама по себе конструкция WITH вполне адекватная
Нет, не в данной конкретной реализации. Конструкция WITH всегда неадекватна когда работает со ссылкой на указатель (VAR x: POINTER TO...) потому, что значение указателя на который ссылается ссылка x всегда можно свободно менять.
-
Нет, не в данной конкретной реализации. Конструкция WITH всегда неадекватна когда работает со ссылкой на указатель (VAR x: POINTER TO...) потому, что значение указателя на который ссылается ссылка x всегда можно свободно менять.
Никак не могу согласиться с данным утверждением, потому как писали мы оберонистый компилятор для внутренних нужд - нет там такой проблемы, потому что дескриптор типа содержит поле guard, которое увеличивается при каждом вхождении в блок WITH и уменьшается при выходе из него, что контролируется при присваивании/создании, и в случае обращения к защищенному участку памяти вываливается исключение, но память при этом, по понятным причинам и стандартными средствами, испортить невозможно.
-
Ничего не понятно :)
Можно подробнее рассказать?
Зачем поле "guard"?
Что значит "контролируется при присваивании/создании"?
Что значит "в случае обращения к защищенному участку памяти"?
В оригинальном Обероне WITH тупой до безобразия. Во время компиляции просто временно меняется тип переменной и далее соответственно разыменования контролируются с этим временным типом (контроль времени компиляции). А у вас я так понимаю в рантайме при каждом разыменовании контроль происходит?
В оригинальном Обероне опять же в рантайме контроль осуществляется ровно один раз при входе в блок WITH.
-
Зачем поле "guard"?
Что значит "контролируется при присваивании/создании"?
Что значит "в случае обращения к защищенному участку памяти"?
Изначально данное поле предназначалось для защиты объектов. Обычно это поле равно 0, что говорит о том, что "дверь открыта" и с объектом (вернее с выделенным участком памяти, где и лежит нужный нам объект) можно делать всё что угодно и кому угодно. Если значение отлично от 0, то объект защищен и его нельзя трогать - нельзя пересоздать (что гарантирует присутствие нужного экземпляра), нельзя собрать сборщиком мусора и т.д., а WITH использует этот механизм для того, чтобы гарантировать неизменность не только типа, но и экземпляра.
В оригинальном Обероне WITH тупой до безобразия. Во время компиляции просто временно меняется тип переменной и далее соответственно разыменования контролируются с этим временным типом (контроль времени компиляции). А у вас я так понимаю в рантайме при каждом разыменовании контроль происходит?
В оригинальном Обероне опять же в рантайме контроль осуществляется ровно один раз при входе в блок WITH.
Ничего не могу сказать про оригинальный Оберон, потому что когда мы писали компилятор я видел только описание языка и никакого реального компилятора у нас не было. Возможно, я неверно интерпретировал описание WITH, потому что в моём понимании любое обращение к защищаемой переменной должно вызывать проверку типа, либо должен быть механизм, гарантирующий неизменность типа и экземпляра. Т.к. это относительно медленное дело, то мы и решили уже имеющийся у нас механизм с полем guard использовать и здесь - ведь залоченный объект гарантированно неизменен (т.е. защищен) и проверять это при каждом обращении совершенно бессмысленно, хотя это тоже поддерживается через ключи компиляции. В тоже время за 7 лет эксплуатации данные предосторожности были использованы только при разработке для отслеживания возможных казусов, и ни разу не сработали, потому что изменение защищенной переменной говорит о дыре не в языке или реализации компилятора, а в голове у программиста.
-
ЗЫ: Почему-то не могу отредактировать свое сообщение, дополню - Под неизменностью экземпляра я имею ввиду неизменность самого экземпляра, но не его данных.
-
Хм... у вас какая-то иная семантика WITH получилась. Я бы даже сказал совсем не WITH ;)
В общем примерно понятно.
Единственное что не понятно это:
В тоже время за 7 лет эксплуатации данные предосторожности были использованы только при разработке для отслеживания возможных казусов, и ни разу не сработали, потому что изменение защищенной переменной говорит о дыре не в языке или реализации компилятора, а в голове у программиста.
Я наверно туплю, но фраза "и ни разу не сработали" меня совсем запутала. :)
И еще не очень понятно как вы разыменования контролируете. Обычным кастингом, как в Оберон-07?
-
ЗЫ: Почему-то не могу отредактировать свое сообщение, дополню - Под неизменностью экземпляра я имею ввиду неизменность самого экземпляра, но не его данных.
Сдается мне я поспешил с фразой "В общем примерно понятно" :D
Постараюсь понять позже на свежую голову.
-
Хм... у вас какая-то иная семантика WITH получилась. Я бы даже сказал совсем не WITH ;)
В общем примерно понятно.
Как я ее тогда понял, так и реализовал )))
Но, в принципе, она примерно так и работает, как ожидается (мной )))
Я наверно туплю, но фраза "и ни разу не сработали" меня совсем запутала. :)
Не сработала в том плане, что ни разу не встретилась ситуация, когда нужно было срабатывать ) не пишем мы такой код и всё тут.
И еще не очень понятно как вы разыменования контролируете. Обычным кастингом, как в Оберон-07?
Не понял, что подразумевается под контролем разыменования и причём здесь кастинг?
Возможно мы о разных вещах думаем, нужен пример кода.
-
ЗЫ: Почему-то не могу отредактировать свое сообщение, дополню - Под неизменностью экземпляра я имею ввиду неизменность самого экземпляра, но не его данных.
Сдается мне я поспешил с фразой "В общем примерно понятно" :D
Это просто я мутно выразился.
Просто если у нас есть, к примеру, указатель P0 на объект, у которого guard#0, то операция P0.x :=123 корректна, а NEW (P0) вызовет исключение, потому что происходит попытка смены экземпляра.
-
Не сработала в том плане, что ни разу не встретилась ситуация, когда нужно было срабатывать ) не пишем мы такой код и всё тут.
Безошибочные кодеры? ;) Тогда можно и на Си писать...
Не понял, что подразумевается под контролем разыменования и причём здесь кастинг?
Возможно мы о разных вещах думаем, нужен пример кода.
MODULE MyTest;
IMPORT Log;
TYPE
T0 = POINTER TO EXTENSIBLE RECORD END;
T1 = POINTER TO RECORD(T0) a: CHAR END;
VAR
V0: T0;
V1: T1;
BEGIN
NEW(V1);
V1.a := "Ы";
V0 := V1;
Log.Char(V0.a); (*Разыменование без охраны. Так низя*)
Log.Char(V0(T1).a); (*Разыменование с обычным кастингом. Так можно*)
END MyTest.
-
В 2005 г., в момент перевода данной статьи, не было известно о дефекте никому из сообщества, мне известного.
Кстати, идите покричите Sun-у (Ораклу), которая ПРОДАВАЛА "безопасную песочницу", в модели байт-кода которой потом университетские исследователи находили фатальные дыры.
1. Я говорю про то что было (и есть ) у ВАС ПОСЛЕ 2005г.
2. Sun, в отличие от вас, свои ошибки признала и работает над ними.. вы, обнаглели, настолько, что паразитируете на них...
-
Это просто я мутно выразился.
Просто если у нас есть, к примеру, указатель P0 на объект, у которого guard#0, то операция P0.x :=123 корректна, а NEW (P0) вызовет исключение, потому что происходит попытка смены экземпляра.
Теперь понятно. Да, это тоже вариант. Правда хочу заметить, что это и есть уточнение семантики WITH, о котором уже говорилось в этой ветке.
-
В данной конкретной реализации, потому что сама по себе конструкция WITH вполне адекватная, а реализовать полностью безопасный механизм не так уж и сложно и оверхед небольшой будет, вполне терпимый, проявляющийся только при lvalue.
М... на тему адекватности мы дискутировали много здесь, но что интересно - Вирт ответил на этот вопрос отрицательно.
-
Да, что-то мы от главной темы ушли :)
У меня еще версия есть:
Это может быть связано с особенностями кодинга под ARM.
Может спросить у него письмом?
-
Можно, но лично, склоняюсь к поддержке идеи Алексея - т.е. он посчитал нецелесообразным поддерживать глобальную защиту участков кода- зачем если можно сделать все локально...-(а может просто, чтобы коровята умылись.... гики они такие :))
-
М... на тему адекватности мы дискутировали много здесь, но что интересно - Вирт ответил на этот вопрос отрицательно.
Так не ответил он ))
А вообще, в таком простом языке как Оберон07 (и, соответственно, в таком простом компиляторе) не нужна такая сложная в реализации вещь как правильный WITH, а вот для "простокастинга" была бы полезна имеющаяся у нас конструкция типа TYPECAST [SAFE] a:x, b:y, c:z ... END;
-
;) Дословно , ДА (не говорил) - но удаление всей конструкции из языка, довольно красноречиво...
-
Kemet, а вы еще и язык изменили?! :)
Можете подробно описать вашу версию Оберона/компилятора в отдельной ветке?
-
Просто если у нас есть, к примеру, указатель P0 на объект, у которого guard#0, то операция P0.x :=123 корректна, а NEW (P0) вызовет исключение, потому что происходит попытка смены экземпляра.
Не понятно. Защита у указателя или у объекта? Если у указателя, то чему равен размер указателя? Какое это имеет отношение к ссылке на указатель? У ссылки тоже есть защита? Какой размер у ссылки? В любом случае, по VAR-ссылке на указатель значение этого указателя в приведённом примере вообще не изменяется:
VAR globalPointer: R0;
...
PROCEDURE f (VAR localPointer: R0);
BEGIN
WITH localPointer: R1 DO (* убедились, что localPointer стопудово указывает на R1 *)
Print(localPointer);
globalPointer := NewR2(); (* начиная с этого места оказывается, что localPointer тоже указывает на R2 *)
Print(localPointer);
globalPointer := NewR3(); (* начиная с этого места оказывается, что localPointer тоже указывает на R3 *)
Print(localPointer)
ELSE
END
END f;
PROCEDURE Do*;
BEGIN
globalPointer := NewR1();
f(globalPointer)
END Do;
Ссылка на указатель localPointer в этой процедуре не трогается. Трогается внешний указатель globalPointer. Его-то трогать можно? Можно! Но тип localPointer при этом меняется. А раз тип localPointer может сколько угодно раз менятся уже после входа в ветку WITH, значит WITH неадекватен.
-
Kemet, а вы еще и язык изменили?! :)
Можете подробно описать вашу версию Оберона/компилятора в отдельной ветке?
Что значит изменили? Расширили! Я не вижу в этом криминала, во первых мы не ставили целью совместимость с оригиналом, нам нужен был удобный (для нас) инструмент.
Возьмите Оберон-2 и компиляторы POW!, XDS, OO2C - это Оберон-2, но скомпилировать код написанный под OO2C не удасться скомпилировать другими компиляторами, кто в этом видит криминал? В то же время, я так думаю, код написанный в соответствии со стандартом Оберон-2 они все скомпилируют.
Я не уверен, что все конструкции Оберона-2 наш компилятор обработает так, как ожидается от компилятора Оберон-2 (но тесты вроде проходят), но мы его никогда и не называли Обероном или Обероном-2 или активным Обероном, мы его называем оберонопободный язык ), а между собой кличем Сириусом )))
Описать, конечно, можно, но, плчему-то, у меня какие-то технические проблемы на этом форуме, то авторизация слетает, то странички не открываются, да и редактировать не могу свои сообщения. Не иначе КомКон бдит (((
-
Сергей, я так понял что у них в момент присваивания глобальному указателю вылетит исключение, т.к. специальное поле guard в этот момент будет не равно 0.
WITH localPointer: R1 DO (* Тут у глобального указателя скрытое поле guard станет равно guard + 1*)
globalPointer := NewR2(); (* Тут исключение *)
Т.е. у них немного другая семантика WITH
-
Описать, конечно, можно, но, плчему-то, у меня какие-то технические проблемы на этом форуме, то авторизация слетает, то странички не открываются, да и редактировать не могу свои сообщения. Не иначе КомКон бдит (((
Сообщения можно редактировать втечение нескольких минут после отправки, затем они замораживаются.
А про авторизацию - ничего не скажу. Не знаю, у меня все нормально и в логах вроде бы ошибок по этому поводу нет.
PS. А тему про сириус можно завести - мне лично весьма любопытно.
-
Кстати, особенно очевидна неадекватность WITH когда процедура Print в указанном выше примере принимает аргумент типа R1, а не R0.
-
Что значит изменили? Расширили! Я не вижу в этом криминала....
Нет нет. Я ничего плохого не имел ввиду. :)
-
...
Защищается объект (участок памяти с ним связанный). Не имеет значения, сколько на него указателей, ссылок, ссылок на указатели, потому что все операции по смене экземпляра блокированы, а значит и любой указатель на объект изменить невозможно по определению - Вы просто не сможете изменить globalPointer, потому что объект, на который он указывает в это время защищён.
Сами указатели не защищены - просто как только указатель оказывается lvalue происходит проверка guard=0 и если это не так значит мы пытаемся отстрелить себе помидоры.
-
И ещё. Ну допустим какими-то хитрокрючкотворными способами удаётся (с потерей производительности) избежать в данном примере порчи памяти. Ну и что? Исключение-то всё равно будет брошено. И случится это во время работы программы, а не во время её компиляции. Между тем в ветке WITH по её семантике тип фиксируется во время компиляции. То есть даже отсутсвие порчи памяти (замена её бросанием исключения) не добавляет адекватности WITH при работе с ссылкой на указатель.
-
.... И случится это во время работы программы, а не во время её компиляции. Между тем в ветке WITH по её семантике тип фиксируется во время компиляции. То есть даже отсутсвие порчи памяти (замена её бросанием исключения) не добавляет адекватности WITH при работе с ссылкой на указатель.
Вот тут я не уверен (точнее, не уверен что изначально речь шла об ошибках времени компиляции) -только в Гардене это было обьявлено четко....
но и мы... находясь под воздействием идей ученичков Вирта , доведенных но абсурда в коровнике- абсолютизируем эту тему... Может быть по проще - примем в качестве отправной точки зрения несостоятельность оных...
-
Защищается объект (участок памяти с ним связанный). Не имеет значения, сколько на него указателей, ссылок, ссылок на указатели, потому что все операции по смене экземпляра блокированы, а значит и любой указатель на объект изменить невозможно по определению - Вы просто не сможете изменить globalPointer, потому что объект, на который он указывает в это время защищён.
Сами указатели не защищены - просто как только указатель оказывается lvalue происходит проверка guard=0 и если это не так значит мы пытаемся отстрелить себе помидоры.
Э-э-э.... сделайте меня так чтобы я это развидел. :) :) :)
Значит всё что вы написали не имеет совершенно никакого отношения к WITH и к Оберонам. В Оберонах присваивание указателей ptr1 := ptr2 можно делать когда угодно и сколько угодно.
Гы-гы-гы, а что там в Сириусе если объект защищён, то ни одному указателю на него нельзя даже NIL присвоить???
-
Сергей - но сказали же вам что другой язык - и называется он Сириус...более того, если, например, реализовать в Обероне предложение Влада - он также перестанет быть им (Обероном)...
-
Короче ждем описания Сириуса! чтоб
потроллить обсудить :D
-
И ещё. Ну допустим какими-то хитрокрючкотворными способами удаётся (с потерей производительности) избежать в данном примере порчи памяти.
Да ничего особохитрого нет - всё прозрачно. Производительность несколько потеряется только на операциях типа NEW, :=, т.к. требуется проверка не защищен ли объект.
Между тем в ветке WITH по её семантике тип фиксируется во время компиляции.
Так ведь это сугубо Ваше личное представление о семантике WITH, ничем не подкрепленное - ничего подобного в описании языка-то нет.
-
Так ведь это сугубо Ваше личное представление о семантике WITH, ничем не подкрепленное - ничего подобного в описании языка-то нет.
Так вот именно что нет. Семантика WITH в Обероне определяет только охрану типа, т.е. запрещено только тип менять, но присваивания не запрещены.
-
Значит всё что вы написали не имеет совершенно никакого отношения к WITH и к Оберонам. В Оберонах присваивание указателей ptr1 := ptr2 можно делать когда угодно и сколько угодно.
Можно, за исключением тех, которые охраняются в данный момент. Это никак не противоречит Оберону, как раз наоборот, полностью соответствует семантике WITH, в моём понимании, но никто пока это не опроверг.
Гы-гы-гы, а что там в Сириусе если объект защищён, то ни одному указателю на него нельзя даже NIL присвоить???
Пока он защищен - нет, иначе зачем его защищать.
-
Смотрите описание:
9.11 Операторы With
Операторы with выполняют последовательность операторов в зависимости от результата проверки типа и применяют охрану типа к каждому вхождению проверяемой переменной внутри этой последовательности операторов.
ОператорWith = WITH Охрана DO ПоследовательностьОператоров {"|" Охрана DO ПоследовательностьОператоров} [ELSE ПоследовательностьОператоров] END.
Охрана = УточнИдент ":" УточнИдент.
Если v - параметр-переменная типа запись или переменная-указатель, и если ее статический тип T0, оператор
WITH v: T1 DO S1 | v: T2 DO S2 ELSE S3 END
имеет следующий смысл: если динамический тип v - T1, то выполняется последовательность операторов S1 в которой v воспринимается так, будто она имеет статический тип T1; иначе, если динамический тип v - T2, выполняется S2, где v воспринимается как имеющая статический тип T2; иначе выполняется S3. T1 и T2 должны быть расширениями T0. Если ни одна проверка типа не удовлетворена, а ELSE отсутствует, программа прерывается.
Пример:
WITH t: CenterTree DO i := t.width; c := t.subnode END
http://www.uni-vologda.ac.ru/oberon/o2rus.htm (http://www.uni-vologda.ac.ru/oberon/o2rus.htm)
Ваша реализация ему противоречит. Тут нет ни слова про запрет присваивания. Следовательно в правильной Оберон программе при вашей реализации WITH может возникнуть исключение.
-
Так вот именно что нет. Семантика WITH в Обероне определяет только охрану типа, т.е. запрещено только тип менять, но присваивания не запрещены.
Может быть, я же не говорю, что я прав. В принципе, разрешить присваивание, но при этом контролировать тип не так уж и сложно, просто добавится проверка типа, это можно ключиком/модификатором WITH сделать - это 10 минут работы, но нужно ли?
-
Ваша реализация ему противоречит. Тут нет ни слова про запрет присваивания. Следовательно в правильной Оберон программе при вашей реализации WITH может возникнуть исключение.
Ну так что не запрещено - разрешено ) Всё, что выше описано наш WITH реализует.
В правильной Оберон программе не меняют охраняемую переменную через другой указатель - какой в этом смысл?
-
Смотрите:
MODULE MyTest;
IMPORT Log;
TYPE
T0 = POINTER TO EXTENSIBLE RECORD END;
T1 = POINTER TO RECORD(T0) a: CHAR END;
VAR
V0: T0;
V1: T1;
V2: T1;
PROCEDURE Do*();
BEGIN
NEW(V1);
V1.a := "Ы";
NEW(V2);
V2.a := "Э";
V0 := V1;
WITH V0: T1 DO
Log.Char(V0.a);
V0 := V2; (* присваивание внутри WITH разрешено, т.к. тут тип не меняется*)
Log.Char(V0.a)
END;
END Do;
BEGIN
END MyTest
-
Нельзя сказать, что оно разрешено - ведь явного разрешения в описании нет, я также могу сказать, что запрещено. Этот спор не имеет смысла, потому что основан на нашем индивидуальном восприятии. Здесь уместней было бы уточнение языка, а так зависит от реализации.
-
Ну так было и в оригинальном Обероне, т.е. это трактовка автора языка. Логика у WITH имхо заключается в том, чтобы не пропустить в рантайм некорректные обращения к полям записи.
Опять же имхо запрет присваиваний внутри WITH не от чего не защищает.
зы Я конечно говорю о Виртовском WITH
-
Почему вы так уверены? Уже проверили на компиляторе Оберона?
Вот например в ЧЯ это не так:
http://oberspace.dyndns.org/index.php/topic,229.msg5368.html#msg5368 (http://oberspace.dyndns.org/index.php/topic,229.msg5368.html#msg5368)
Так Вирт ЧЯ не писал. У меня его нет, проверить не могу.
А если PROCEDURE f (VAR localPointer: R0); заменить на
PROCEDURE f (localPointer: R0);
проблема воспроизводится?
-
А с чего бы ей так воспроизводиться?
-
А с чего бы ей так воспроизводиться?
Хех, так ведь тогда проблема-то не в WITH
-
Все это уже обсуждалось
...Плюс везде запретить передавать глобальные переменные VAR параметром...
-
Все это уже обсуждалось
...Плюс везде запретить передавать глобальные переменные VAR параметром...
Обсуждалось, но, видимо, выводы вы сделали неправильные, потому-что проблема не в WITH и не в передаче глобальных параметров, а в интерпретации указателей, передаваемых по ссылке.
-
А интерпретация может быть иной?
-
А интерпретация может быть иной?
В контексте WITH да.
Мы ведь должны получить ссылку на экземпляр, чтобы выполнить приведение динамического типа к статическому, а у них либо такая инфа теряется, что маловероятно, либо, получив ссылку на указатель они уже считают её ссылкой на экземпляр, тогда как для var-параметра необходимо проверить не указатель ли там, и разыменовать его.
-
Проверил ETH Oberon (эмулятор под винду)
Печатает в логе
R1
R2
R3
и.... падает!
вот код:
MODULE Test2;
IMPORT Out;
TYPE
R0 = POINTER TO RECORD END;
R1 = POINTER TO RECORD (R0) a: ARRAY 100 OF CHAR END;
R2 = POINTER TO RECORD (R0) END;
R3 = POINTER TO RECORD (R0) END;
VAR
globalPointer: R0;
PROCEDURE NewR1 (): R1;
VAR x: R1;
BEGIN NEW(x); RETURN x
END NewR1;
PROCEDURE NewR2 (): R2;
VAR x: R2;
BEGIN NEW(x); RETURN x
END NewR2;
PROCEDURE NewR3 (): R3;
VAR x: R3;
BEGIN NEW(x); RETURN x
END NewR3;
PROCEDURE Print (x: R0);
BEGIN
IF x IS R1 THEN Out.String("R1"); Out.Ln
ELSIF x IS R2 THEN Out.String("R2"); Out.Ln
ELSIF x IS R3 THEN Out.String("R3"); Out.Ln
END
END Print;
PROCEDURE f (VAR localPointer: R0);
VAR
a: INTEGER;
BEGIN
WITH localPointer: R1 DO
Print(localPointer);
globalPointer := NewR2();
Print(localPointer); localPointer.a := "jsdfdfkjghdfkjgkjdfgjdkfhgkjdfhgkjdfghkjdfhgkjdfhgkjdfhgkjdhfgkjhdfkjghdfk";
globalPointer := NewR3();
Print(localPointer)
END
END f;
PROCEDURE Do*;
BEGIN
globalPointer := NewR1();
f(globalPointer)
END Do;
BEGIN
END Test2.
Compiler.Compile Test2
Test2.Do
-
ilovb, я скачал сейчас bb1.6, после пятиминутного замешательства, связанного с разглядыванием сего чуда, мне удалось вставить, скомпилировать и 30 раз выполнить выше приведенный(на предыдущих страницах) исходный код. 30 раз он напечатал R1, R2, R3, но не упал, может надо запускать большее количество раз?
-
ilovb, я скачал сейчас bb1.6, после пятиминутного замешательства, связанного с разглядыванием сего чуда, мне удалось вставить, скомпилировать и 30 раз выполнить выше приведенный(на предыдущих страницах) исходный код. 30 раз он напечатал R1, R2, R3, но не упал, может надо запускать большее количество раз?
Порча памяти совсем не обязательно приводит к падению (в этом то и проблема :-) ). В ряде случаев программа будет тихо мирно но не корректно работать после этого. А может и корректно работать. А может и упасть через полгода после инцидента.
-
он напечатал R1, R2, R3, но не упал
Для показательной неадекватности WITH применённого к ссылке на указатель достаточно того, что он напечатал R1, R2, R3 вместо R1, R1, R1. А уж когда он там упадёт или бросит исключение - вопрос второй.
-
На 37 разе он среагировал грозными сообщениями и в окне появилась сетка, и потом он упал. Надо будет исходники глянуть.
-
Kemet, если давить на коммандер удерживая "ctrl", то эффект быстрее достигается
-
достаточно того, что он напечатал R1, R2, R3 вместо R1, R1, R1. А уж когда он там упадёт или бросит исключение - вопрос второй.
Это очевидно, я с этим никак не спорю, мне хотелось увидеть реакцию на порчу памяти.
-
Проверил ETH Oberon (эмулятор под винду)
Вру. Это не эмулятор, а порт. Т.е. компилер там не виртовский, а OP2
-
Пока нет времени вдумчиво исследовать исходники компилятора КП из ЧЯ1.6Ю но, просмотрев с десяток строк кода я увидел такую интересную конструкцию
(id - это охраняемая переменная)
IF (id # NIL) & (id.typ.form = Pointer) & ((id.mode = VarPar) OR ~id.leaf) THEN
err(-302) (* warning 302 *)
END ;
-
Проверил ETH Oberon (эмулятор под винду)
Вру. Это не эмулятор, а порт. Т.е. компилер там не виртовский, а OP2
а КП основан на ОП2 со всеми вытекающими
-
Пока нет времени вдумчиво исследовать исходники компилятора КП из ЧЯ1.6Ю но, просмотрев с десяток строк кода я увидел такую интересную конструкцию
(id - это охраняемая переменная)
IF (id # NIL) & (id.typ.form = Pointer) & ((id.mode = VarPar) OR ~id.leaf) THEN
err(-302) (* warning 302 *)
END ;
Как мне кажется, здесь, по логике, должен стоять запрет на передачу в WITH var pointer, т.е. компилятор должен дать нам по рукам, но не дает, значит условие не выполняется...
-
Я не знаю как перекомпилить ЧЯ, может кто-нибудь посмотреть, что в id.typ.form
и id.mode при передаче var pointer - это в CPP строка 1451
-
Я не знаю как перекомпилить ЧЯ, может кто-нибудь посмотреть, что в id.typ.form
и id.mode при передаче var pointer - это в CPP строка 1451
На всякий случай напоминаю, что исходники ББ есть онлайн - см. шапку форума:
Онлайн исходники BlackBox: тут (http://oberspace.dyndns.org/WeBB/):WeBB и на github (https://github.com/valexey/BlackBox-Component-Builder)
Может быть удобным при обсуждении.
-
Я не знаю как перекомпилить ЧЯ, может кто-нибудь посмотреть, что в id.typ.form
и id.mode при передаче var pointer - это в CPP строка 1451
На всякий случай напоминаю, что исходники ББ есть онлайн - см. шапку форума:
Онлайн исходники BlackBox: тут (http://oberspace.dyndns.org/WeBB/):WeBB и на github (https://github.com/valexey/BlackBox-Component-Builder)
Может быть удобным при обсуждении.
В частности на интуресующую строку можно было просто дать ссылку (https://github.com/valexey/BlackBox-Component-Builder/blob/master/Dev/Mod/CPP.cp#L1451).
-
В частности на интуресующую строку можно было просто дать ссылку (https://github.com/valexey/BlackBox-Component-Builder/blob/master/Dev/Mod/CPP.cp#L1451).
Там она 1438 (https://github.com/valexey/BlackBox-Component-Builder/blob/master/Dev/Mod/CPP.cp#L1438).
-
А вот это любопытно...
...
3. Warnings
...
302 guarded variable can be side-effected
...
-
А вот это любопытно...
...
3. Warnings
...
302 guarded variable can be side-effected
...
Так я и говорю, что проблема не в WITH, а в другом месте.
Получается, что они, всё-таки, потеряли информацию о том, что это ссылка, и условие не выполнилось.
Всё-ж таки надо вывод участвующих в вычислении условия переменных, может кто-то сделать? Но, подозреваю, VarPar не установлен
-
Все там работает как надо. Это не логика компиляции, а просто предупреждение.
Меня вот интересует почему оно на экран не выводится. Код этот срабатывает в нашем случае (я проверил)
Вывод предупреждений видимо по дефолту выключен. Где это включить пока в упор не вижу...
-
Все там работает как надо. Это не логика компиляции, а просто предупреждение.
Меня вот интересует почему оно на экран не выводится. Код этот срабатывает в нашем случае (я проверил)
Вывод предупреждений видимо по дефолту выключен. Где это включить пока в упор не вижу...
Всё-ж таки выполняется? Меня смутило отсутствие реакции. Пусть не ошибка, а хотя-бы предупреждение о проблеме должно было быть, а тишина, и мертвые с косами вдоль дорог стоят...
-
Вывод предупреждений видимо по дефолту выключен. Где это включить пока в упор не вижу...
CPM PROCEDURE Mark*
забавно там
-
Вот процедура из модуля DevCPM, которая собирает ошибки:
PROCEDURE Mark* (n, pos: INTEGER);
BEGIN
(*StdLog.Int(n);*)
IF (n >= 0) & ~((oberon IN options) & (n >= 181) & (n <= 190)) THEN
noerr := FALSE;
IF pos < 0 THEN pos := 0 END;
IF (pos < lastpos) OR (lastpos + 9 < pos) THEN
lastpos := pos;
IF errors < maxErrors THEN
errNo[errors] := n; errPos[errors] := pos
END;
INC(errors)
END;
IF trap IN options THEN HALT(100) END;
ELSIF (n <= -700) & (errors < maxErrors) THEN
errNo[errors] := -n; errPos[errors] := pos; INC(errors)
END
END Mark;
Ошибка с кодом -302 тупо игнорится...
p.s. Жирным выделена моя вставка
-
забавно там
Ага ;D
Они знали....
-
Блин у меня даже прям слов нет... Одни эмоции....
-
Может там, всё-таки, должно стоять
(n >= -700)
чтобы хотябы варнинги вывести потом
-
Кстати, в ЧЯ1.5 код идентичен
-
Скорее всего 302 должно быть без минуса просто. Они минус наверно в этих целях и использовали при написании компилятора.
Т.е. поставил минус - ошибка не выводится....
А вот специально они ентот минус оставили или случайно - это уже загадка.
-
Кстати там это единственная ошибка с минусом
В этом можно убедиться сделав поиск: ctrl+F "err(-"
-
Ну может в коммерческой версии минус меняется на плюс, а пипл и так схавает
-
Тык это и есть коммерческая версия
-
Хех... убрал минус и наш код перестал компилиться ;D
-
Наверно лучше просто предупреждение выводить все таки....
p.s. Написал Ивану Денисову об этом косяке.
-
p.s. Написал Ивану Денисову об этом косяке.
А кто это
-
Координатор красноярской сборки BB 1.6
http://oberoncore.ru/projects/bb16ru-kras (http://oberoncore.ru/projects/bb16ru-kras)
-
Илья, а тебе не надоело постоянно ругаться с людьми? Враждовать? Вещать истину? Особенно из-за такого пустяка как Оберон? :)
Меня всегда удивляет/забавляет факт, что в жизни (на работе, в бизнесе, в моём городе, всюду, где я лично общаюсь с людьми) у меня практически нет конфликтов/врагов.
В Сети, однако, всё по-другому. Объяснений этому феномену найти пока не могу.
-
Продублирую ценный пост:
Вы почитайте диссертацию Шиперски, там есть вещи и похуже. Например, в операторе WITH есть дефект. Там не гарантируется сохранность указателя, у которого уже определили тип, внутри тела WITH. Стр. 210:
Код:
TYPE
P = POINTER TO R;
R = RECORD END;
P1= POINTER TO R1;
R1 = RECORD (R) x: INTEGER END;
PROCEDURE F;
VAR p:P; p1:P1;
PROCEDURE G;
BEGIN NEW(p) END G;
BEGIN NEW(p1);p:=p1;
WITH p: P1 DO
p.x:=0; (*legal, since p has been guarded to P1 *)
G; (*this destroys the assertion of the WITH guard*)
p.x := 42 (*havoc!!*)
END
END F;
http://forum.oberoncore.ru/viewtopic.php?f=114&t=3836&start=40#p72578 (http://forum.oberoncore.ru/viewtopic.php?f=114&t=3836&start=40#p72578)
-
Oberon Type System Loopholes
WITH applied to designators of pointer type
It is possible to alter a guarded pointer variable within the scope of a guarding WITH statement. For example:
TYPE
P = POINTER TO R;
R = RECORD END;
P1 = POINTER TO R1;
R1 = RECORD (R) x: INTEGER END;
PROCEDURE F;
VAR p: P; p1: P1;
PROCEDURE G;
BEGIN NEW(p) END G;
BEGIN
NEW(p1);
p := p1;
WITH p: P1 DO
p.x := 0; (* legal, since p has been guarded to P1 *)
G; (* this destroys the assertion of the WITH guard *)
p.x := 42; (* havoc! *)
END
END F;
So, it is best not to use the WITH statement on POINTER variables.
(Without a global (inter-module) consistancy check a compiler cannot accurately detect problematic code.)
SYSTEM.BYTE compatibility rule
The language defines a special compatibility rule (Oberon Language Report, Appendix A):
Module SYSTEM exports the data type BYTE. No representation of values is
specified. Instead, certain compatibility rules with other types are given:
(1) The type BYTE is compatible with CHAR and SHORTINT.
(2) If a formal variable parameter is of type ARRAY OF BYTE then the
corresponding actual parameter may be of any type.
Rule 2 is a loophole in the type-system and should generally be avoided. For example, suppose the module Util has the following routine:
PROCEDURE Dummy (VAR x: ARRAY OF SYSTEM.BYTE);
If a client of Util calls Util.Dummy with a pointer as parameter, the invariant that pointers always point to a valid object on the heap (or are NIL) can be invalidated by Dummy since it can overwrite the pointer with any value. Note that the client didnt even import SYSTEM to declare itself an unsafe module.
SYSTEM.PTR compatibility rule
The Oberon-2 (not Oberon) language report (in appendix C) defines another special compatibility rule: Variables of any pointer type may be assigned to variables of type SYSTEM.PTR. If a formal variable parameter is of type PTR, the actual parameter may be of any pointer type.
This leads to the following loophole in the type-system: The type of a pointer-variable bound to a VAR parameter can be changed inside of a procedure (by an assignment), and the changed value be passed outside in violation of the type system.
Credits:
The material here is taken from the ETHOS book by C. Szyperski and from the Lagoona paper by M. Franz.
http://web.archive.org/web/20040530183405/http://www.math.tau.ac.il/~guy/Oberon/pitfalls.html (http://web.archive.org/web/20040530183405/http://www.math.tau.ac.il/~guy/Oberon/pitfalls.html)
-
Safety hazards in Oberon compilers and systems
This page lists problems with common implementations NOT with the language.
The page is a joint effort. If you know of any more problems or changes in the implementation that exhibit these problems please let me know. Thanks to S. Ludwig for most of the contents.
Numeric and stack overflow detection disabled by default
Some Oberon implementation dont by default generate code for detection of numeric overflows and stack overflows. If you have more details about specific implementations please let me know
POINTER TO ARRAY OF POINTER garbage collection problem
In some Oberon System implentations the garbage-collector doesnt mark the pointers within a POINTER TO ARRAY OF POINTER. This means the elements may be garbage-collected although they are still referenced.
Implementations exhibiting this problem (incomplete list): ETH Sparc V4, Amiga Oberon.
Stack garbage collection problem
This occurs when a procedure that has a VAR parameter which is the only reference left to a heap object. Example:
TYPE
Node = POINTER TO NodeDesc;
NodeDesc = RECORD val: INTEGER END;
VAR x: Node;
PROCEDURE Havoc(VAR val: INTEGER);
VAR y: Node;
BEGIN
x := NIL; (* destroys last reference to x *)
NEW(y); (* may cause GC, thus freeing 'x', if val is not treated as a po
inter into 'x' *)
INC(val) (* memory havoc! *)
END Havoc;
BEGIN
NEW(x); x.val := 15; Havoc(x.val)
END
Implementations exhibiting this problem (incomplete list): ETH DEC-Oberon V4, ETH HP-Oberon V4
Dangling procedure variables
Under all Oberon Systems it is possible to unload a module while there are procedure variables which refer to procedures in it.
http://web.archive.org/web/20040530181509/http://www.math.tau.ac.il/~guy/Oberon/compiler-probs.html (http://web.archive.org/web/20040530181509/http://www.math.tau.ac.il/~guy/Oberon/compiler-probs.html)
-
2 ilovb Коль скоро занимаетесь "ворошением дерьма" - т разумно будет создать ветку "Известные недостатки реализаций Обероно подобных систем" - и закрепив ее в шапке форума копипастить туда примеры с комментариями... :( крайне полезно для новичков попавших под действие коровьей пропаганды... да и зарвавшихся ушлых коровят макать мордой туда можно будет...
-
2 ilovb Коль скоро занимаетесь "ворошением дерьма" - т разумно будет создать ветку "Известные недостатки реализаций Обероно подобных систем" - и закрепив ее в шапке форума копипастить туда примеры с комментариями... :( крайне полезно для новичков попавших под действие коровьей пропаганды... да и зарвавшихся ушлых коровят макать мордой туда можно будет...
Че ж так злобно-то? :) Просто "мифы и факты". Обрисовать границы пресловутой герметичности типов и ограничения дизайна известных оберон систем (почему они такие простые, а виндовс/линукс такие сложные). Без фанатизму :)
-
Продублирую ценный пост:
Вы почитайте диссертацию Шиперски, там есть вещи и похуже. Например, в операторе WITH есть дефект. Там не гарантируется сохранность указателя, у которого уже определили тип, внутри тела WITH. Стр. 210:
...
Ссылка на диссертацию:
http://research.microsoft.com/en-us/um/people/cszypers/books/Insight-EthOS.pdf (http://research.microsoft.com/en-us/um/people/cszypers/books/Insight-EthOS.pdf)
-
2 ilovb Коль скоро занимаетесь "ворошением дерьма" - т разумно будет создать ветку "Известные недостатки реализаций Обероно подобных систем" - и закрепив ее в шапке форума копипастить туда примеры с комментариями... :( крайне полезно для новичков попавших под действие коровьей пропаганды... да и зарвавшихся ушлых коровят макать мордой туда можно будет...
Че ж так злобно-то? :) Просто "мифы и факты". Обрисовать границы пресловутой герметичности типов и ограничения дизайна известных оберон систем (почему они такие простые, а виндовс/линукс такие сложные). Без фанатизму :)
В смысле ? злобное название? - с моей точки зрения -"Известные недостатки реализаций Обероно подобных систем" по делу а "мифы и факты" - это "творчество" со всеми возможными последствиями...
Насчет коровят - "есть такая буква" суть претензий
1. СОЗНАТЕЛЬНОЕ извращение сути оригинальных источников.
2. Попытки манипулирования сознанием "неофитов" с использованием заведомо ложных (и им известных) аргументов и этически-недопустимых методов.
3. Неадекватность коровят (пример - ВСЕ сообщения Ильи и других функционеров-коровцев на ЭТОМ форуме - на замечания - уход в сторону, и сообщения в стиле "срал, сру и буду срать" - в коровнике ответ один - эцилоп Темиргалеев ). Вы считаете что они не заслужили подобного ответа?
-
Насчет коровят - "есть такая буква" суть претензий
1. СОЗНАТЕЛЬНОЕ извращение сути оригинальных источников.
Ну это из серии "я так вижу". С этим ничего не сделаешь и это всегда так будет.
2. Попытки манипулирования сознанием "неофитов" с использованием заведомо ложных (и им известных) аргументов и этически-недопустимых методов.
Это да, коробит. Если "не говорить правду до конца" я могу списать на педагогические соображения, то вранье - не может быть оправдано.
3. Неадекватность коровят (пример - ВСЕ сообщения Ильи и других функционеров-коровцев на ЭТОМ форуме - на замечания - уход в сторону, и сообщения в стиле "срал, сру и буду срать" - в коровнике ответ один - эцилоп Темиргалеев ).
Илья самый адекватный оппонент "с той стороны" и я рад, что он навещает нас на нашем форуме. При том, что я с ним, как правило, не согласен :) Причем он имеет непосредственное отношение к производству ПО и с ним можно обсуждать технические вопросы. Эдакая противоположность info21, который не имеет отношения к производству и с которым нельзя ничего обсудить (даже при нормальном модерировании). И, кстати, Илья более чем спокойно реагирует на эмоциональные нападки.
Вы считаете что они не заслужили подобного ответа?
Я считаю, что все бурные эмоции со срывом масок alexus'а и т.п. (которые я очень даже понимаю) можно уже было выплеснуть и использовать форум для чего-то более конструктивного. Благо теперь есть альтернативная площадка для людей, которым интересно критически посмотреть на современное программирование - без какой-то генеральной линии партии.
Я бы не хотел делить людей на "оттуда" и "отсюда", даже если сюда придет сам Темиргалеев :) Здесь другой форум, другой формат общения, а не только прямая оппозиция "тому" форуму и сведение счетов.
-
Ну это из серии "я так вижу". С этим ничего не сделаешь и это всегда так будет.
Это из серии - "нех мочиться в бочку из которой пьешь" - Откуда вы думаете в основном берутся "умные" книги на которые любите ссылаться - как обобщение исследовательских статей... а их пишут в общем то обычные люди, которые могут ошибаться и ошибаются...многие жалеют об ошибках- но, как говориться, что написано пером - трудно вырубить топором... Но глумиться над работами, так как это делают в коровнике... ИМХО слишком жестоко по отношению к авторам.(хотя я не высокого мнения о творениях команды Вирта).
]
Илья самый адекватный оппонент "с той стороны" и я рад, что он навещает нас на нашем форуме. При том, что я с ним, как правило, не согласен :) Причем он имеет непосредственное отношение к производству ПО и с ним можно обсуждать технические вопросы. Эдакая противоположность info21, который не имеет отношения к производству и с которым нельзя ничего обсудить (даже при нормальном модерировании). И, кстати, Илья более чем спокойно реагирует на эмоциональные нападки.
офигеть , какое достижение - впрочем, если сравнивать с Темиргалеевым....И действительно по сравнению с Инфо21 - небо и земля, последний не смотря на свою мезантропичность, умеет связать вместе пару предложений... и единственный кто в коровнике делает что то для развития ББ- в рамках своего видения. А насчет отношения к производству... - тем больше я слушаю Илью , тем больше сомневаюсь в этом.. как и в других вещах им же самодекларируемых..
Я считаю, что все бурные эмоции со срывом масок alexus'а и т.п. (которые я очень даже понимаю) можно уже было выплеснуть и использовать форум для чего-то более конструктивного. Благо теперь есть альтернативная площадка для людей, которым интересно критически посмотреть на современное программирование - без какой-то генеральной линии партии.
Я бы не хотел делить людей на "оттуда" и "отсюда", даже если сюда придет сам Темиргалеев :) Здесь другой форум, другой формат общения, а не только прямая оппозиция "тому" форуму и сведение счетов.
Это не ответ на вопрос... По поводу Вашего взгляда на вещи - Ну так делайте (ВЫ) - этот форум более конструктивным-в чем проблема? -никто Вас здесь не затыкает ;)
-
даже если сюда придет сам Темиргалеев :)
Кстати, на днях Термигалеев бессмысленно и беспощадно забанил Петра Алмазова за то, что Пётр посмел написать:
Из архива достать изволили?
Так может и удалять не надо было?
http://forum.oberoncore.ru/viewtopic.php?p=72579#p72579
Peter Almazov давал ссылку на Шиперского про ошибку в WITH, этот материал был удалён, а сейчас Термигалеев неподумавши достал копию из "подвала", а чтобы не оправдываться перед Алмазовым просто забанил его.
Так что нет, если Термигалеев не мазохист, то на форум где он не модератор ему своё свинячье рыло лучше не совать.
-
Проверил древный, клятый всеми Pow! - там многоветочный WITH - компилятор честно выдаёт предупреждение Warning 9: guarded variable can be side-effected
Эх, если бы в Pow! линкер был написан на обероне, а так опять переписывать ((
-
Эх, если бы в Pow! линкер был написан на обероне, а так опять переписывать ((
А зачем компоновщик на обероне?
-
The WITH statement:
This [compiler error] has to be a bug, correct me if I'm wrong! (I'm going nuts over this)
TYPE
Obj* = POINTER TO Empty;
Empty = RECORD (*nothing*) END;
OpObj = POINTER TO OpNode;
OpNode = RECORD (Empty)
name : CHAR;
left, right : Obj;
END;
PROCEDURE doeval (ex: Obj): REAL;
BEGIN
WITH ex : OpObj DO
CASE ex.name OF
"+" : RETURN doeval(ex.left (* err 113 *))
+ doeval(ex.right (* err 113 *));
"-" : (* clever code here *)
"*" : (* more clever code *)
"/" : (* you get the idea *)
END;
(* et cetera *)
END;
END doeval;
Error #133 is an "incompatible assignment". ex.left and ex.right certainly seem to be of type Obj. Why won't doeval accept them?
As thutt@clark.net (Taylor Hutt) points out,
This is not a bug. The WITH statement actually changes the static type of the WITHed variable for the entire duration of the WITH statement. A workaround to this problem is to assign the parameter to a temporary variable and to use the WITH on the temp. A type guard will not work properly in this case, do not attempt to use it.
Some people on Comp.lang.oberon think that the WITH statement should be avoided entirely because of its non-local effects. They point out that a programmer can use individual type guards or, if a guarded variable is used very many times, can pass the variable to a procedure.
http://users.cms.caltech.edu/~cs140/140a/Oberon/language_faq.html
-
Сомнения у меня по поводу этого
TYPE
P = POINTER TO R;
R = RECORD END;
P1= POINTER TO R1;
R1 = RECORD (R) x: INTEGER END;
PROCEDURE F;
VAR p:P; p1:P1;
PROCEDURE G;
BEGIN NEW(p) END G;
BEGIN NEW(p1);p:=p1;
WITH p: P1 DO
p.x:=0; (*legal, since p has been guarded to P1 *)
G; (*this destroys the assertion of the WITH guard*)
p.x := 42 (*havoc!!*)
END
END F;
With statements execute a statement sequence depending on the result of a type test and apply a type guard to every occurrence of the tested variable within this statement sequence.
Т.е. p внутри WITH должно заменяться на p(P1) и на p.x := 42 программа должна рухнуть.
-
В каком смысле "рухнуть"? Трап?
-
Т.е. p внутри WITH должно заменяться на p(P1)
Можно, конечно, и так трактовать. Но, во-первых, это неэффективно. А во-вторых:
и на p.x := 42 программа должна рухнуть.
это не то, что ожидается от такой конструкции.
-
... на 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.
-
Ну тык у akron1 и язык другой :)
-
... на 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);
-
Было бы очень странно если б оно не падало:
В смысле? Там же обычное приведение к наследнику, коим и является (по факту) p. В данном примере похоже на багу компилятора.
-
Было бы очень странно если б оно не падало:
В смысле? Там же обычное приведение к наследнику, коим и является (по факту) p. В данном примере похоже на багу компилятора.
Сказано же:
it aborts program execution
Не удалось привести тип? Давай, досвидания - креш.
-
Не удалось привести тип? Давай, досвидания - креш.
Почему не удалось-то? Посмотри пример - там создается (NEW) наследник и к нему же идет приведение (через указатель на базу).
-
Не удалось привести тип? Давай, досвидания - креш.
Почему не удалось-то? Посмотри пример - там создается (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;
Вопросы? Пожелания? Коментарии?
-
Там создается предок и его пытаются привести к наследнику:
Где???
P1 = POINTER TO R1;
R1 = RECORD (R) x: INTEGER END;
Еще раз по-русски: P1 это указатель на R1, являющуюся расширением R. Т.е. создается R1. И к ней же кастается.
NEW(p);
Посмотри оригинал - там NEW(p1);
-
Там создается предок и его пытаются привести к наследнику:
Где???
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) ? ;-)
-
Ну и где тут NEW(p1) ? ;-)
Фуцк! У меня скроллер в оригинальном сообщении в аккурат скрывал второй NEW.
-
Ну и где тут NEW(p1) ? ;-)
Фуцк! У меня скроллер в оригинальном сообщении в аккурат скрывал второй NEW.
Вот что бывает когда весь логический кусок кода не влазит на один экран!
-
это не то, что ожидается от такой конструкции.
А что ожидается ?
-
А что ожидается ?
Ожидается проверка типа (один раз) и использование переменной проверенного типа (множество раз). Без трапов.
-
Совсем без трапов не бывает. Никто же не помешает сделать p := NIL; p.x :=42;
-
Совсем без трапов не бывает. Никто же не помешает сделать p := NIL; p.x :=42;
А разименовывание нулевого указателя/ссылки это разве трап? По крайней мере в Обероне-07, вроде как нет. Никакого трапа не требуется.
-
Совсем без трапов не бывает. Никто же не помешает сделать p := NIL; p.x :=42;
Здесь есть принципиальная разница. Язык разрешает занулять поинтеры. Поэтому трап в этом случае вполне ожидаем. Но язык не позволяет написать p := pBase, если p имеет тип указателя на наследника (он таким становится после проверки WITH). То, что есть неявные средства поработать с p "опять" как с указателем на базовый тип - изъян дизайна. Который довольно легко лечится без кардинальной передлки языка. Решений предлагалось несколько. Но Вирт, как всегда, предпочел лечить проблему избавлением от проблемной конструкции. Хотя может он был даже и не в курсе проблемы - просто выпилил WITH, потому что в данный момент оно ему не надо.
-
Предлагаемые лекарства сводятся к удалению WITH из языка и введению новой конструкции с другой семантикой. Первую часть плана Вирт уже выполнил. :)
-
А зачем он вообще нужен, этот WITH? Во-первых, он избыточен, во-вторых, его назначение в Обероне-07 совершенно отличается от его же назначения в Паскале.
Удалил его Вирт -- ну и хорошо, нефиг лишние сущности плодить без необходимости...
-
А зачем он вообще нужен, этот WITH?
Он нужен, чтобы использование message bus не выглядело таким страшным. Кроме того WITH сочетает проверку/приведение типа. Без WITH - это две отдельные операции (менее эффективно).
-
А зачем он вообще нужен, этот WITH?
Он нужен, чтобы использование message bus не выглядело таким страшным. Кроме того WITH сочетает проверку/приведение типа. Без WITH - это две отдельные операции (менее эффективно).
Синтаксический сахар, то есть.
Ну, у Вирта лишь одно средство борьбы с раком, вызываемым синтаксическим сахаром, и он им воспользовался, удалив этот WITH... ;D