OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 27 Январь, 2022 04:51

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




Начать новую тему Ответить на тему  [ Сообщений: 12 ] 
Автор Сообщение
 Заголовок сообщения: Неоднородное поведение IS
СообщениеДобавлено: Суббота, 20 Ноябрь, 2021 19:28 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 530
Коллеги, вот такой пример демонстрирует, что 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 не была должным образом поправлена, и бывшая осмысленной проверка типа стала бессмысленной. Отказавшись это компилировать, компилятор помог бы выявить потенциальную ошибку в логике программы.

Что скажете?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Суббота, 20 Ноябрь, 2021 19:38 

Зарегистрирован: Пятница, 11 Январь, 2019 19:26
Сообщения: 260
Откуда: Russia
это же статическая проверка, то есть проводится во время компиляции, так как проверка e IS Ext всегда истинна


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Воскресенье, 21 Ноябрь, 2021 12:14 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3195
Если обработчик должен что-то сделать по VAR параметру, то вполне жизненная вот такая история, когда на входе может быть NIL.

Код:
PROCEDURE Create (VAR e: Base)
BEGIN

IF e IS Ext THEN
  NEW(e);
  e.field := 1;
ELSE
  NEW(e)
END;

END Create;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Воскресенье, 21 Ноябрь, 2021 15:32 

Зарегистрирован: Воскресенье, 28 Май, 2006 22:12
Сообщения: 1693
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^).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Воскресенье, 21 Ноябрь, 2021 18:12 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1411
adimetrius писал(а):
Но в моем примере формальный тип (статический) переменной е - концевой

Это неважно, b IS Base тоже всегда истинно.
Отказываться компилировать -довольно странно. Это то же, что отказываться компилировать IF 2+2=4 THEN ...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Воскресенье, 21 Ноябрь, 2021 18:53 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1333
Откуда: Киев
adimetrius писал(а):
Мне кажется, что правильнее было бы проверку e IS Ext не заменять на инвариантную ИСТИНУ, а отказываться компилировать.
Всё верно, было бы разумно не позволять IS через такое расширение определения extension
Цитата:
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
По той же причине, почему не позволено IS к базовому типу, хотя с логической точки зрения оно тоже корректно, но всего лишь всегда истинно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Понедельник, 22 Ноябрь, 2021 09:34 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9447
Откуда: Россия, Орёл
Иван Денисов писал(а):
Если обработчик должен что-то сделать по 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 - указательный тип, то там строго, ты расширенный не передашь.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Понедельник, 22 Ноябрь, 2021 09:57 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3195
Илья Ермаков писал(а):
Иван, так если e - указательный тип, то там строго, ты расширенный не передашь.

И правда.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Понедельник, 22 Ноябрь, 2021 11:02 
Аватара пользователя

Зарегистрирован: Пятница, 11 Май, 2007 21:57
Сообщения: 1488
Откуда: Украина, Киев
А у Delphi-нистов IS считается "хорошим тоном" проверки на NIL. Возможны, например, ситуации, что указатель не нулевой, но там какой-то мусор.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Среда, 24 Ноябрь, 2021 14:30 

Зарегистрирован: Воскресенье, 28 Май, 2006 22:12
Сообщения: 1693
Ярослав Романченко писал(а):
А у Delphi-нистов IS считается "хорошим тоном" проверки на NIL. Возможны, например, ситуации, что указатель не нулевой, но там какой-то мусор.

Есть слабая аналогия со случаем, когда непонятно, что возвращать из метода удаления элемента из коллекции - истину или ложь, - если этого элемента.нет в коллекции. :)
То есть: нет, такого элемента нет в коллекции. По сути мы получили, что хотели - возвращаем истину.
Или - наоборот - раз искомого элемента нет в коллекции, значит требование на его удаление было ошибочным - возвращаем ложь. :)
Для оператора IS - есть много неоднозначностей из-за его "логического полиморфизма".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Пятница, 26 Ноябрь, 2021 23:38 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2425
Откуда: Россия, Томск
Ярослав Романченко писал(а):
А у Delphi-нистов IS считается "хорошим тоном" проверки на NIL. Возможны, например, ситуации, что указатель не нулевой, но там какой-то мусор.

Не знаю насчёт хорошего тона, но вроде как в Delphi is всегда бросает исключение при применении на nil. Всегда нужно проверять if Assigned(x) and (x is TSomething) then...
Или я что-то упустил?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Неоднородное поведение IS
СообщениеДобавлено: Вторник, 30 Ноябрь, 2021 15:59 
Аватара пользователя

Зарегистрирован: Пятница, 11 Май, 2007 21:57
Сообщения: 1488
Откуда: Украина, Киев
Александр Ильин писал(а):
Или я что-то упустил?
То я передал Вам слово-в-слово что обычно говорят в "компаниях", использующих Delphi :)
А реальность такова, что IS ни "проверяет на мусор" ни выбрасывает исключение.
Но Assigned() не помогает точно так же! :lol: Мусорные указатели, на самом деле - большая проблема. Надо следить, что-бы они в коде не порождались. Для этого рекомендуют избегать использования .Free, а пользоваться FreeAndNil(), например.
Простой пример:
Код:
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


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

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


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

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


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

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