Нежданчик: with НЕ экранирует собственные проперти в методе

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Нежданчик: with НЕ экранирует собственные проперти в методе

Сообщение Cheb » 28.01.2015 13:18:41

Нарвался пытаясь сэкономить (не корысти ради, а только велением душащей меня жабы) на вызове as.

Код: Выделить всё
  procedure TTextureLikeAsset.Devour(c: TGenericAsset);
  begin
    with (c as TTextureLikeAsset) do begin
      f_width:= Width;
      f_height:= Height;
    end;
    inherited Devour(c);
  end;

- и прилетела мне птица обломинго. :x Компилятор засчитал Width как Self.Width, и программа душераздирающе упала уже в рантайме.

Пришлось заменить на
Код: Выделить всё
  procedure TTextureLikeAsset.Devour(c: TGenericAsset);
  begin
    f_width:= (c as TTextureLikeAsset).Width;
    f_height:= (c as TTextureLikeAsset).Height;
    inherited Devour(c);
  end;

- и всё пучком.
А если там таких полей стопицот? Компилятор догадается соптимизировать вызовы as? Сомневаюсь. :(
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Re: Нежданчик: with НЕ экранирует собственные проперти в мет

Сообщение hinst » 28.01.2015 13:29:10

сделай переменную; либо только первый вызов as, а все последующие - ()
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: Нежданчик: with НЕ экранирует собственные проперти в мет

Сообщение Cheb » 28.01.2015 17:07:21

сделай переменную;

Строго говоря, в моём случае вес as пренебрежим (поскольку сопровождает или "толстое" обращение к OpenGL или загрузку полсотни мегабайт с диска).

Я просто хотел поделиться подводным камнем :(

а все последующие - ()

Ы :?: :(

Добавлено спустя 1 минуту 50 секунд:
Re: Нежданчик: with НЕ экранирует собственные проперти в методе
:!: Я ещё думал: может, это баг? С дельфёй есть кто-нить, проверить?
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Re: Нежданчик: with НЕ экранирует собственные проперти в мет

Сообщение pupsik » 28.01.2015 17:16:53

душащей меня жабы
жаба хороша - писанины меньше... :D

Код: Выделить всё
      f_width:= Width;
      f_height:= Height;
и какая версия фпс и лазаря сие делает. И это только в одной системе (?) или везде...
Просто не замечал подобного.

либо только первый вызов as, а все последующие - ()
а можно пример, а то чет туплю :oops:
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: Нежданчик: with НЕ экранирует собственные проперти в мет

Сообщение sign » 29.01.2015 07:01:36

Cheb писал(а):Нарвался пытаясь сэкономить (не корысти ради, а только велением душащей меня жабы) на вызове as.

Код: Выделить всё
  procedure TTextureLikeAsset.Devour(c: TGenericAsset);
  begin
    with (c as TTextureLikeAsset) do begin
      f_width:= Width;
      f_height:= Height;
    end;
    inherited Devour(c);
  end;

- и прилетела мне птица обломинго. :x Компилятор засчитал Width как Self.Width, и программа душераздирающе упала уже в рантайме.

Пришлось заменить на
Код: Выделить всё
  procedure TTextureLikeAsset.Devour(c: TGenericAsset);
  begin
    f_width:= (c as TTextureLikeAsset).Width;
    f_height:= (c as TTextureLikeAsset).Height;
    inherited Devour(c);
  end;

- и всё пучком.
А если там таких полей стопицот? Компилятор догадается соптимизировать вызовы as? Сомневаюсь. :(

Странно.
Я мне приходится дописывать Self. И именно потому, что в with цепляются не Self.Width, а width параметра.
IDE 1.2.6
FPC 2.6.4
Windows XP3
sign
энтузиаст
 
Сообщения: 1131
Зарегистрирован: 30.08.2009 09:20:53

Re: Нежданчик: with НЕ экранирует собственные проперти в мет

Сообщение Alexx2000 » 29.01.2015 21:31:08

pupsik писал(а):а можно пример, а то чет туплю :oops:

Код: Выделить всё
    f_width:= (c as TTextureLikeAsset).Width;
    f_height:= TTextureLikeAsset(c).Height;
Аватара пользователя
Alexx2000
постоялец
 
Сообщения: 489
Зарегистрирован: 25.10.2006 00:22:07
Откуда: Мытищи

Re: Нежданчик: with НЕ экранирует собственные проперти в мет

Сообщение Cheb » 04.02.2015 09:55:39

Мне очень стыдно, что не додумался сам :oops:

Конечно же! Весь смысл оператора as - поднять исключение если попадётся левый класс не из той ветки наследования.
Все последующие as просто не имеют физического смысла: либо класс подходит и достаточно тупого тайпкаста, либо исключение уже было поднято, и исполнение дотуда просто не дошло :facepalm: Ну я тупооой :cry:
Аватара пользователя
Cheb
энтузиаст
 
Сообщения: 994
Зарегистрирован: 06.06.2005 15:54:34

Re: Нежданчик: with НЕ экранирует собственные проперти в мет

Сообщение Stertor » 15.02.2015 20:44:37

with (c as TTextureLikeAsset) do begin
:facepalm: :facepalm: :facepalm: :facepalm: :facepalm:
Аватара пользователя
Stertor
новенький
 
Сообщения: 20
Зарегистрирован: 10.08.2014 18:11:12

Re: Нежданчик: with НЕ экранирует собственные проперти в мет

Сообщение MylnikovDm » 24.02.2015 11:10:24

а вариант with TTextureLikeAsset(c) do begin
работает правильно?
Если да, то может переделать на явную проверку совместимости типа?
Код: Выделить всё
if c is TTextureLikeAsset then 
  with TTextureLikeAsset(c) do begin
  ...
  end;

если вам так уж нужно генерирование исключения, то добавте секцию else и сгенерируйте его там.

Другой вариант, сделать локальную переменную нужного типа, присвоить её через as, а дальше воткнуть в with
Код: Выделить всё
procedure TTextureLikeAsset.Devour(c: TGenericAsset);
var
  t: TTextureLikeAsset;
begin
    t := c as TTextureLikeAsset;
    with t do begin
      f_width:= Width;
      f_height:= Height;
    end;
    inherited Devour(c);
  end;
MylnikovDm
постоялец
 
Сообщения: 103
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Re: Нежданчик: with НЕ экранирует собственные проперти в мет

Сообщение Tango » 19.05.2015 15:25:44

Считаю with вредным и опасным, как раз из-за вот такой непредсказуемости.
Аватара пользователя
Tango
постоялец
 
Сообщения: 162
Зарегистрирован: 31.05.2012 17:07:30


Вернуться в Free Pascal Compiler

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

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

Рейтинг@Mail.ru
cron