Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2006.12.24;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.049 c
3-1160635701
GanibalLector
2006-10-12 10:48
2006.12.24
проблемы с FireBird1.5


2-1165398195
horse
2006-12-06 12:43
2006.12.24
ShellExecute


15-1165237556
Рамиль
2006-12-04 16:05
2006.12.24
Альтернатива Enterprise Manager для MS SQL Express


2-1164922852
azl
2006-12-01 00:40
2006.12.24
Как удалить в тексте из 3-х строк первые 2 строки?


15-1165248006
oldman
2006-12-04 19:00
2006.12.24
Наши опять взяли Кубок Девиса...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский