Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.12.24;
Скачать: CL | DM;

Вниз

Вычисление булевых выражений   Найти похожие ветки 

 
pasha_golub ©   (2006-11-30 11:37) [0]

Прямо мистика какая-то. В среде включено укороченное вычесление, по умолчанию.

Имеется код:


 If Assigned(APrevFocusedNode) and APrevFocusedNode.Values[tlcCompositeModified.ItemIndex] then
...


APrevFocusedNode = nil на момент выполнения этой инструкции. По идее, не должно происходить дальнейшего вычисления. А оно происходит, и ясен пень, с вылетом на AV.

Думал какие-то настройки локальные вмешались. Прямо перед строкой этой поставил:

{$BOOLEVAL OFF}

Не помогло. Поставил {$B-}, эффект тот же самый.

Попробовал перестроить условие:

 If Assigned(APrevFocusedNode) then
 If APrevFocusedNode.Values[tlcCompositeModified.ItemIndex] then


Так работает без ошибки.

Вопрос: почему так происходит?


 
vuk ©   (2006-11-30 11:43) [1]

Попробовать можно следующие варианты:
1. Отключить оптимизацию
2. Заменить Assigned на сравнение с nil


 
pasha_golub ©   (2006-11-30 11:46) [2]


> 1. Отключить оптимизацию

Попробовал. Не помогло.

Сейчас второе...


 
pasha_golub ©   (2006-11-30 11:48) [3]

If (APrevFocusedNode <> nil) and APrevFocusedNode.Values[tlcCompositeModified.ItemIndex] then

Тоже не сработало


 
pasha_golub ©   (2006-11-30 11:52) [4]


function VarToBoolDef(const V: Variant; const ADefault: boolean): boolean;
begin
 Result := ADefault;
 if V <> Null then try
   Result := V;
 except
   Result := ADefault
 end;
end;

If (APrevFocusedNode <> nil) and VarToBoolDef(APrevFocusedNode.Values[tlcCompositeModified.ItemIndex],False) then


А вот если так, то работает.


 
umbra ©   (2006-11-30 11:56) [5]

наверное APrevFocusedNode <> nil


 
pasha_golub ©   (2006-11-30 12:00) [6]


> наверное APrevFocusedNode <> nil
>

http://www.farata.kr.ua/FTP/other/debug.png

Триста раз проверил.


 
pasha_golub ©   (2006-11-30 12:04) [7]

Я так понимаю дело в том, что:

   property Values[Index: Integer]: Variant read GetValue write SetValue;

И, наверное, происходят какие-то манипуляции с подготовкой этих вариантов. Может быть такое?


 
Юрий Зотов ©   (2006-11-30 12:04) [8]

Паш, надеюсь, после изменения опций ты делал Build (причем Build All), а не просто Compile?


 
vuk ©   (2006-11-30 12:05) [9]

А можно увидеть что конкретно сгенерил компилятор?


 
pasha_golub ©   (2006-11-30 12:10) [10]


> Юрий Зотов ©   (30.11.06 12:04) [8]
>
> Паш, надеюсь, после изменения опций ты делал Build (причем
> Build All), а не просто Compile?
>

Да, конечно.


> vuk ©   (30.11.06 12:05) [9]
>
> А можно увидеть что конкретно сгенерил компилятор?

В смысле CPU окошко? Не нашел как скопипастить, сейчас сделаю скрин.


 
vuk ©   (2006-11-30 12:12) [11]

>Не нашел как скопипастить, сейчас сделаю скрин.
Не, ну совсем обленился! :o)


 
pasha_golub ©   (2006-11-30 12:13) [12]

Окошечно ЦПУ:

http://www.farata.kr.ua/FTP/other/debug1.png (9Кб)


 
pasha_golub ©   (2006-11-30 12:14) [13]


> Не, ну совсем обленился! :o)

Думал, сначалу руками набрать, но потом подумал, что лучше исключить фактор кривизны. ;0)


 
wal ©   (2006-11-30 12:21) [14]

Вот оно, так как второе значение - вариант, то первое тоже приводится к варианту, над ними выполняется and, результат приводится boolean. Почему именно так - хз, видимо где-то какой то приоритет битовых операций над логическими.


 
vuk ©   (2006-11-30 12:23) [15]

Я может чего не понял, но по ходу пьессы, получается, что не вариант приводится к boolean, а результат первого сравнения без всякого анализа конвертируется в вариант (VarFromBool), потом принудительно при помощи VarAnd производится логическая операция со второй частью, где все и обламывается.


 
pasha_golub ©   (2006-11-30 12:24) [16]


> wal ©   (30.11.06 12:21) [14]

Действительно. Интересный факт оказывается. И налететь на него можно с размаху, и не понять в чем дело.


 
Суслик ©   (2006-11-30 12:27) [17]

А опциях всего проекта что стоит по поводу bool eval?


 
Суслик ©   (2006-11-30 12:28) [18]

Дельфи, кстати, какой?


 
wal ©   (2006-11-30 12:29) [19]


> [16] pasha_golub ©   (30.11.06 12:24)
Порылся в хелпе:
Except for comparisons, which always return a Boolean result, any operation on a variant value returns a variant result. If an expression combines variants with statically-typed values, the statically-typed values are automatically converted to variants.


 
pasha_golub ©   (2006-11-30 12:30) [20]


> Суслик ©   (30.11.06 12:27) [17]
>
> А опциях всего проекта что стоит по поводу bool eval?
>

В первом же посте писал: отключено complete boolean eval


 
pasha_golub ©   (2006-11-30 12:32) [21]


> Суслик ©   (30.11.06 12:28) [18]
>
> Дельфи, кстати, какой?
>

D7


> wal ©   (30.11.06 12:29) [19]

Thanks. Надо себе в память заложить!!!


 
Суслик ©   (2006-11-30 12:32) [22]


>  [20] pasha_golub ©   (30.11.06 12:30)

прости, не заметил :)


 
Суслик ©   (2006-11-30 12:32) [23]

Да... факт интересный.


 
vuk ©   (2006-11-30 12:33) [24]

Кстати, а что будет, если написать

If Assigned(APrevFocusedNode) and (APrevFocusedNode.Values[tlcCompositeModified.ItemIndex] = true) ?


 
pasha_golub ©   (2006-11-30 12:35) [25]


> vuk ©   (30.11.06 12:33) [24]


> If Assigned(APrevFocusedNode) and (APrevFocusedNode.Values[tlcCompositeModified.
> ItemIndex] = true)

Сработало, как и ожидалось. Но тут на лицо явное мошенничество. :)


 
vuk ©   (2006-11-30 12:39) [26]

>Но тут на лицо явное мошенничество. :)
Нет. Таким образом мы просто сделали преобразование в другом месте и  получили сравнение уже двух булевых переменных.


 
Anatoly Podgoretsky ©   (2006-11-30 12:40) [27]

> vuk  (30.11.2006 12:23:15)  [15]

Налицо полное вычисление выражения.


 
Anatoly Podgoretsky ©   (2006-11-30 12:41) [28]

> pasha_golub  (30.11.2006 12:30:20)  [20]

По приведено снимку видно, что ни о каких boolean eval говорить не приходится.


 
pasha_golub ©   (2006-11-30 12:43) [29]


> Anatoly Podgoretsky ©   (30.11.06 12:41) [28]

В первом посте сказано:


> В среде включено укороченное вычесление


Кстати, ошибку заметил. :) Вычисление...


 
Anatoly Podgoretsky ©   (2006-11-30 12:45) [30]

> pasha_golub  (30.11.2006 12:35:25)  [25]

Ну ты понял, никаких булевых вычислений нет если вторая часть вариант, а во втором случае есть, за счет простого трюка.
Но решение ты знаешь, когда не уверен в булевых вычислениях делай в два приема

if 1 then
  if 2 then

Это гарантирует и полную независимост от настроек и от подобных фокусов по замене логических выражений на операции с вариантами.


 
vuk ©   (2006-11-30 12:47) [31]

to Anatoly Podgoretsky ©   (30.11.06 12:40) [27]:
>Налицо полное вычисление выражения.
Похоже, что компилятор решил, что для вычисления выражения нужно все вычисления делать в вариантах и уже потом получать из этого boolean. А and он в данном случае мог вообще трактовать не как логический, а как побитовый. Судя по тому что он сгенерировал, так и вышло.


 
Суслик ©   (2006-11-30 12:50) [32]

Я все-таки не понял, *зачем* компилятор вычислял второе выражение?
Ну ясное дело, что variant"ы. Но полностью то вычислять зачем

Признаюсь я до конца не понял приведенную выше ссылку на доку:

Except for comparisons, which always return a Boolean result, any operation on a variant value returns a variant result. If an expression combines variants with statically-typed values, the statically-typed values are automatically converted to variants.

Ну сказано здесь, что он к вариантам приводит. Но это имеется в виду, что он код генерит, который приводит. Зачем генерить код, который вычисляет второй параметр?

Объясните пжлст.


 
wal ©   (2006-11-30 12:53) [33]


> Зачем генерить код, который вычисляет второй параметр?
Чтобы в результате and вернуть вариант, единственное исключение, когда в результате не вариант - операции сравнения.


 
Суслик ©   (2006-11-30 12:54) [34]

Я может быть тупой, но вычислять то зачем?
Вернуть можно и не вычисляя.


 
Суслик ©   (2006-11-30 12:55) [35]

Т.е. я не вижу из доки того факта, что вычисляться должны оба выражения.


 
Суслик ©   (2006-11-30 12:55) [36]

Собственно интерес простой - может это баг?
Тогда его запостить нужно в QC.


 
pasha_golub ©   (2006-11-30 13:03) [37]


> Суслик ©   (30.11.06 12:55) [36]
>
> Собственно интерес простой - может это баг?
> Тогда его запостить нужно в QC.

В принципе, я тоже склоняюсь к данному мнению.


 
wal ©   (2006-11-30 13:04) [38]


> [34] Суслик ©   (30.11.06 12:54)
Потомучто Variant(False) и False - вещи разные


 
wal ©   (2006-11-30 13:08) [39]


> [36] Суслик ©   (30.11.06 12:55)
Это поведение описано в хелпе, какой же это баг?


 
Anatoly Podgoretsky ©   (2006-11-30 13:17) [40]

> pasha_golub  (30.11.2006 12:43:29)  [29]

Включено, только ни о каких логических вычислениях и речи нет, вот пример, который ты обозвал трюком, как раз честный, идет логическое вычисление и слева и справа Boolean



Страницы: 1 2 вся ветка

Текущий архив: 2006.12.24;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.05 c
15-1165341922
Kolan
2006-12-05 21:05
2006.12.24
Тут у меня спросили чем паттерн от template отличается.


4-1155543437
TRyaSS
2006-08-14 12:17
2006.12.24
Как определить состояние принтера(готов, не подключен,...)?


15-1165016744
ImageList1
2006-12-02 02:45
2006.12.24
Как сохранить все картинки из TImageList ?


15-1164882791
hero
2006-11-30 13:33
2006.12.24
Помогите разобраться с adsl модемом, мне нужно использовать радми


2-1165171129
atas-sheriff
2006-12-03 21:38
2006.12.24
Поиск