AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX Blogs
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 18.06.2009, 15:05   #1  
Blog bot is offline
Blog bot
Участник
 
25,643 / 848 (80) +++++++
Регистрация: 28.10.2006
axaptapedia: Trap typecast
Источник: http://www.axaptapedia.com/Trap_typecast
==============

Summary: caution trap in implicit typecast int64 to boolean

== Typecast from int64(RecId) to boolean ==
(tested in DynamicsAX 2009)

the implicit typecast from int/int64 to boolean is often used in ax sources...

select * from table where table.field == blabla
if (table.recid)


public boolean exist( EDT _value)
{
return (select * from table where table.field == _value).recId;
}


BUT.....

when the RecId (as 64bit integer) last 8 bits are 0
the typecast results in a false even though the RecId is not 0

so, take a look at the bestpractice (design patterns for table exist method)

'''when you'll need a boolean, than use a boolean expression !!!'''

if (table.RecId != 0)












[[category:caution trap]]


Источник: http://www.axaptapedia.com/Trap_typecast
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.
Старый 19.06.2009, 16:38   #2  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 868 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Ностальгия елки-иголки
Старый 19.06.2009, 17:04   #3  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от Wamr Посмотреть сообщение
Ага, тоже сразу вспомнилась эта ветка
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 23.06.2009, 11:10   #4  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5803 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Самое интересное, что if() работает корректно - проблема возникает лишь при присваивании значения int64 булевской переменной:
X++:
Int64   i = 0x7fffffffffffffff;
str     hexI;
boolean b;
boolean c;
Counter n;
;
for (n = 0; n < 8; n++)
{
    b = i ? true : false;
    c = i;
    hexI = strfmt("0x%1%2", int2hex(i >> 32, 8), int2hex(i & 0xffffffffu, 8));
    info(strfmt("if (%1) -> (boolean) %2; %1 -> (boolean) %3", hexI, b, c));
    i = (i << 8) ^ 0x8000000000000000u;
}
Код:
if (0x7FFFFFFFFFFFFFFF) -> (boolean) true; 0x7FFFFFFFFFFFFFFF -> (boolean) true
if (0x7FFFFFFFFFFFFF00) -> (boolean) true; 0x7FFFFFFFFFFFFF00 -> (boolean) true
if (0x7FFFFFFFFFFF0000) -> (boolean) true; 0x7FFFFFFFFFFF0000 -> (boolean) true
if (0x7FFFFFFFFF000000) -> (boolean) true; 0x7FFFFFFFFF000000 -> (boolean) true
if (0x7FFFFFFF00000000) -> (boolean) true; 0x7FFFFFFF00000000 -> (boolean) false
if (0x7FFFFF0000000000) -> (boolean) true; 0x7FFFFF0000000000 -> (boolean) false
if (0x7FFF000000000000) -> (boolean) true; 0x7FFF000000000000 -> (boolean) false
if (0x7F00000000000000) -> (boolean) true; 0x7F00000000000000 -> (boolean) false
Проверялось на ядре AX 2009 v5.0.495.0

Последний раз редактировалось gl00mie; 23.06.2009 в 11:13.
Старый 23.06.2009, 11:30   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,971 / 3268 (116) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Эхх...
Старые баги на новый лад

Кстати получается что все Exists методы на таблицах надо править теперь ? Или будет нормально работать ?
Старый 23.06.2009, 14:45   #6  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5803 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от Logger Посмотреть сообщение
Кстати получается что все Exists методы на таблицах надо править теперь ? Или будет нормально работать ?
Вопрос, конечно, интересный Тесты показывают, что описанный глюк возникает (по крайней мере, в AX2009) в следующих случаях:
  • присвоение переменной типа boolean значения типа Int64 с нулевыми младшими 32-мя (а не 8-ю, как утверждалось в исходном сообщении) разрядами;
  • присвоение переменной другого перечислимого типа значения типа Int/Int64 с нулевыми младшими 8-ю разрядами;
Если, к примеру, значение Int64 используется в выражении как операнд логической функции, например
X++:
boolean ret = _salesId && salesTable.RecId;
то глюк не воспроизводится, равно как и при использовании Int64 в операторе if, в т.ч. в форме тернарного оператора ? :
X++:
boolean ret = record.RecId ? true : false;
Но самое интересное то, что ядро не производит приведение типа для возвращаемого значения функции, т.е. для функции вида
X++:
boolean func()
{
    // ...
    return record.RecId
}
приведение типа будет произведено лишь при вычислении выражения, где непосредственно используется возвращаемое функцией значение, а не перед возвратом управления из нее. Это можно легко увидеть на таком примере:
X++:
Int64   i;
boolean test()
{
    return 0x7fffffff00000000;
}
;
i = test();
info( strfmt('%1', i) );
Таким образом, если функция с типом возвращаемого значения boolean на самом деле возвращает значение типа Int64, то возникнет ли описанный в этой теме глюк или нет, будет зависеть от характера использования значения функции. В случае
X++:
if (test()) // ...
глюк не возникнет, а вот поведение такого кода
X++:
boolean b = test();
if (b) // ...
будет зависеть от того, какое именно ненулевое число вернет test() под видом boolean. В общем, лучше, конечно, сомнительные места в методах exist() исправить; для поиска таких мест был написан простенький job, выводящий список табличных методов exist() с "сомнительным" использованием значений RecId. Сразу скажу, что у job'а наблюдаются ложные срабатывания, тем не менее, в том же приложении ax2009 было найдено 63 потенциально "проблемных" табличных методов exist() (на sys-слое), из которых минимум половина нуждается в исправлении с учетом описанного глюка - во всяком случае, покуда не вышло исправленное ядро.
X++:
#define.RecIdPattern        ('[.]RecId')
#define.RecIdNEZeroPattern  ('[.]RecId[ ]*!=[ ]*0')

UtilElements    utilElements;
UtilEntryLevel  currentLayer;
TreeNodePath    treeNodePath;
TreeNode        treeNode;
Source          sourceCode;
Set             setOfMethods;
Counter         n;
;
setOfMethods = new Set( Types::String );
currentLayer = currentAOLayer();
while select    utilElements
    order by parentId, utilLevel
    where       utilElements.recordType == UtilElementType::TableStaticMethod
        &&      utilElements.utilLevel  <= currentLayer
        &&      utilElements.name       like '*exist*'
        &&  !(  utilElements.name       like '*txtNotExist*' )
{
    treeNodePath = xUtilElements::getNodePath( utilElements );
    if (!setOfMethods.in( treeNodePath ))
    {
        treeNode    = TreeNode::findNode( treeNodePath );
        sourceCode  = SysUtil::unpackSource( treeNode.AOTgetSource() );
        if (    match( #RecIdPattern,       sourceCode )
            && !match( #RecIdNEZeroPattern, sourceCode )

           )
        {
            n++;
            setOfMethods.add( treeNodePath );
            info( strfmt( @"%1::%2() (%3)", tableid2name(utilElements.parentId), utilElements.name, utilElements.utilLevel ), '', SysInfoAction_Editor::newOpen( treeNodePath ) );
        }
    }
}
if (n)
{
    info( strfmt( "@SYS26824", n ) );
}
else
{
    warning( "@SYS4205" );
}
За это сообщение автора поблагодарили: mazzy (2), Zabr (3), Logger (8), alex55 (2).
Старый 23.06.2009, 16:10   #7  
Zabr is offline
Zabr
Участник
Axapta Retail User
 
1,202 / 345 (14) ++++++
Регистрация: 26.06.2002
Адрес: Москва
Спасибо. У нас на Ax 4.0 SP2 + KorusAxaptaRetail = нашлось аж 105 таких табличных методов: половина на SYS и SYP, половина на GLS.
Теги
ax2009, ax4.0, int64, recid, баг, приведение типов, ядро

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
axaptapedia: Tutorial Password Blog bot DAX Blogs 1 22.05.2009 21:23
axcoder: PowerShell + Ax Blog bot DAX Blogs 1 09.01.2009 18:05
axaptapedia: Load Web Documents Blog bot DAX Blogs 1 03.01.2009 23:50
axcoder: AxPath is supported by axaptapedia Blog bot DAX Blogs 0 11.05.2007 10:00

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 13:59.