Показать сообщение отдельно
Старый 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).