Форум: "Прочее";
Текущий архив: 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