OberonCore https://forum.oberoncore.ru/ |
|
Неоднородное поведение IS https://forum.oberoncore.ru/viewtopic.php?f=29&t=6818 |
Страница 1 из 1 |
Автор: | adimetrius [ Суббота, 20 Ноябрь, 2021 19:28 ] |
Заголовок сообщения: | Неоднородное поведение IS |
Коллеги, вот такой пример демонстрирует, что IS иногда определен для неопределенных переменных, а иногда - нет: Код: TYPE Base = POINTER TO EXTENSIBLE RECORD END; Ext = POINTER TO RECORD (Base) END; PROCEDURE P*; VAR e: Ext; b: Base; BEGIN IF e IS Ext THEN Log.String("(e = NIL) & (e IS Ext)"); Log.Ln END; (*1*)IF b IS Ext THEN Log.String("unreachable"); Log.Ln END END P; Эта программа вычисляет e IS Ext = TRUE, выводит сообщение в журнал, и затем аварийно останавливается в (*1*). Для меня было неожиданно, что e IS Ext определено при e = NIL, я ожидал авост. В сообщении о языке сказано: Цитата: 8.2.5 Relations v IS T stands for "the dynamic type of v is T (or an extension of T)" and is called a type test. It is applicable if 1. v is an IN or VAR parameter of record type or v is a pointer to a record type, and if 2. T is an extension of the static type of v ..... Appendix A A type Tb is an extension of a type Ta (Ta is a base type of Tb) if 1. Ta and Tb are the same types Т.е. как я понимаю, случай v = NIL не оговаривается; остается только домысливать, что поскольку v = NIL, то ее фактический тип (динамический) не определен, и потому IS также не определен. Но в моем примере формальный тип (статический) переменной е - концевой, поэтому любое значение, кроме NIL - типа Ext; вероятно, поэтому компилятор "оптимизирует" и вместо вычисления сразу вставляет ИСТИНУ. Мне кажется, что правильнее было бы проверку e IS Ext не заменять на инвариантную ИСТИНУ, а отказываться компилировать. Поскольку в приведенном примере она бессмысленна, ее присутствие в тексте - вероятно, следствие того, что Ext ранее был расширяемым типом, а потом, при редактировании программы, стал концевым. А процедура P не была должным образом поправлена, и бывшая осмысленной проверка типа стала бессмысленной. Отказавшись это компилировать, компилятор помог бы выявить потенциальную ошибку в логике программы. Что скажете? |
Автор: | Sergej Durmanov [ Суббота, 20 Ноябрь, 2021 19:38 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
это же статическая проверка, то есть проводится во время компиляции, так как проверка e IS Ext всегда истинна |
Автор: | Иван Денисов [ Воскресенье, 21 Ноябрь, 2021 12:14 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
Если обработчик должен что-то сделать по VAR параметру, то вполне жизненная вот такая история, когда на входе может быть NIL. Код: PROCEDURE Create (VAR e: Base)
BEGIN IF e IS Ext THEN NEW(e); e.field := 1; ELSE NEW(e) END; END Create; |
Автор: | Wlad [ Воскресенье, 21 Ноябрь, 2021 15:32 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
adimetrius писал(а): Коллеги, вот такой пример демонстрирует, что IS иногда определен для неопределенных переменных, а иногда - нет: Код: Base = POINTER TO EXTENSIBLE RECORD END; Ext = POINTER TO RECORD (Base) END; Эта программа вычисляет e IS Ext = TRUE, ... . Для меня было неожиданно, что e IS Ext определено при e = NIL, я ожидал авост. ... Что скажете? Так разработчик компилятора прав. Ext - указатель на нерасширяемую запись ("лист" дерева наследования). Ранее, что-то, что было присвоено переменной этого типа прошло проверку (раз мы здесь оказались и исполняемся). Cледовательно, буде этот указатель NIL или нет - он ВСЕГДА указывает на переменную записи типа "терминального наследника" (Ext^). |
Автор: | Trurl [ Воскресенье, 21 Ноябрь, 2021 18:12 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
adimetrius писал(а): Но в моем примере формальный тип (статический) переменной е - концевой Это неважно, b IS Base тоже всегда истинно. Отказываться компилировать -довольно странно. Это то же, что отказываться компилировать IF 2+2=4 THEN ... |
Автор: | Comdiv [ Воскресенье, 21 Ноябрь, 2021 18:53 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
adimetrius писал(а): Мне кажется, что правильнее было бы проверку e IS Ext не заменять на инвариантную ИСТИНУ, а отказываться компилировать. Всё верно, было бы разумно не позволять IS через такое расширение определения extensionЦитата: A type Tb is an extension of a type Ta (Ta is a base type of Tb) if По той же причине, почему не позволено IS к базовому типу, хотя с логической точки зрения оно тоже корректно, но всего лишь всегда истинно.
1. Ta and Tb are the same types |
Автор: | Илья Ермаков [ Понедельник, 22 Ноябрь, 2021 09:34 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
Иван Денисов писал(а): Если обработчик должен что-то сделать по VAR параметру, то вполне жизненная вот такая история, когда на входе может быть NIL. Код: PROCEDURE Create (VAR e: Base) BEGIN IF e IS Ext THEN NEW(e); e.field := 1; ELSE NEW(e) END; END Create; Иван, так если e - указательный тип, то там строго, ты расширенный не передашь. |
Автор: | Иван Денисов [ Понедельник, 22 Ноябрь, 2021 09:57 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
Илья Ермаков писал(а): Иван, так если e - указательный тип, то там строго, ты расширенный не передашь. И правда. |
Автор: | Ярослав Романченко [ Понедельник, 22 Ноябрь, 2021 11:02 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
А у Delphi-нистов IS считается "хорошим тоном" проверки на NIL. Возможны, например, ситуации, что указатель не нулевой, но там какой-то мусор. |
Автор: | Wlad [ Среда, 24 Ноябрь, 2021 14:30 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
Ярослав Романченко писал(а): А у Delphi-нистов IS считается "хорошим тоном" проверки на NIL. Возможны, например, ситуации, что указатель не нулевой, но там какой-то мусор. Есть слабая аналогия со случаем, когда непонятно, что возвращать из метода удаления элемента из коллекции - истину или ложь, - если этого элемента.нет в коллекции. ![]() То есть: нет, такого элемента нет в коллекции. По сути мы получили, что хотели - возвращаем истину. Или - наоборот - раз искомого элемента нет в коллекции, значит требование на его удаление было ошибочным - возвращаем ложь. ![]() Для оператора IS - есть много неоднозначностей из-за его "логического полиморфизма". |
Автор: | Александр Ильин [ Пятница, 26 Ноябрь, 2021 23:38 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
Ярослав Романченко писал(а): А у Delphi-нистов IS считается "хорошим тоном" проверки на NIL. Возможны, например, ситуации, что указатель не нулевой, но там какой-то мусор. Не знаю насчёт хорошего тона, но вроде как в Delphi is всегда бросает исключение при применении на nil. Всегда нужно проверять if Assigned(x) and (x is TSomething) then... Или я что-то упустил? |
Автор: | Ярослав Романченко [ Вторник, 30 Ноябрь, 2021 15:59 ] |
Заголовок сообщения: | Re: Неоднородное поведение IS |
Александр Ильин писал(а): Или я что-то упустил? То я передал Вам слово-в-слово что обычно говорят в "компаниях", использующих Delphi ![]() А реальность такова, что IS ни "проверяет на мусор" ни выбрасывает исключение. Но Assigned() не помогает точно так же! ![]() Простой пример: Код: var покажет:list1, list2: TList; begin list1 := TList.Create; list1.Free; if list1 is TList then ShowMessage('After call to list.Free the list is TList') else ShowMessage('After call to list.Free the list isn''t TList'); if Assigned(list1) then ShowMessage('After call to list.Free the list is assigned') else ShowMessage('After call to list.Free the list isn''t assigned'); list2 := TList.Create; FreeAndNil(list2); if list2 is TList then ShowMessage('After call to FreeAndNil(list) the list is TList') else ShowMessage('After call to FreeAndNil(list) the list isn''t TList'); if Assigned(list2) then ShowMessage('After call to FreeAndNil(list) the list is assigned') else ShowMessage('After call to FreeAndNil(list) the list isn''t assigned'); Цитата: After call to list.Free the list is TList
After call to list.Free the list is assigned After call to FreeAndNil(list) the list isn't TList After call to FreeAndNil(list) the list isn't assigned |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |