Ошибки, баги, вопросы - страница 1205

 
Renat:

Снимайте поштучно запущенные индикаторы и эксперты, чтобы понять в чем проблема.

Чтобы узнать детали, нажмите на кнопку "Details" в окне описания ошибки. Скопируйте сюда полный текст, пожалуйста.

Я так понимаю Вам это надо?

 

 crash -->  000007FCE8441F4F 48396B10          cmp        [rbx+0x10], rbp

              000007FCE8441F53 7530              jnz        0x7fce8441f85


              000007FCE8441F55 488B03            mov        rax, [rbx]

              000007FCE8441F58 4C8BCF            mov        r9, rdi

              000007FCE8441F5B 4D8BC7            mov        r8, r15

              000007FCE8441F5E 8BD6              mov        edx, esi

              000007FCE8441F60 488BCB            mov        rcx, rbx


            : #021 00000000000011C8 EIP: 0000000000000000 ESP: 0000000000000000 


            : #022 0000000000001068 EIP: 000007FCF54245DB ESP: 0000006818CFFAC8 

              000007FCF54245D1:00000A [000007FCF54245DB] NtYieldExecution (ntdll.dll)

              000007FCF5426E50:000833 [000007FCF5427683] RtlUnicodeStringToInteger (ntdll.dll)

              000007FCF3681828:00001A [000007FCF3681842] BaseThreadInitThunk (kernel32.dll)

              000007FCF54774E8:000021 [000007FCF5477509] RtlVerifyVersionInfo (ntdll.dll)


            : #023 000000000000111C EIP: 000007FCF54245DB ESP: 0000006818E5FB18 

              000007FCF54245D1:00000A [000007FCF54245DB] NtYieldExecution (ntdll.dll)

              000007FCF5426E50:000833 [000007FCF5427683] RtlUnicodeStringToInteger (ntdll.dll)

              000007FCF3681828:00001A [000007FCF3681842] BaseThreadInitThunk (kernel32.dll)

              000007FCF54774E8:000021 [000007FCF5477509] RtlVerifyVersionInfo (ntdll.dll)

 
полный текст отправил личным сообщением
 

Тут в процессе разбора предыдущего примера выяснилось принципиальное различие между MQL и C++

class A {};
class B : public A {};
class C {
public:
        virtual int g( A* a ) { return ( 1 ); }
        virtual int g( B* b ) { return ( 2 ); } //здесь полное совпадение
};
class D : public C {
public:
        virtual int g( A* a ) { return ( 3 ); }
};
void OnStart()
{
        B* b = new B;
        D* d = new D;
        Print( d.g( b ));
}

в MQL(build 978) результат: 2 (вызывается С::g), а в С++ результат: 3 (вызывается D::g)

Получается, что MQL отдает приоритет точному совпадению типа аргумента, даже если оно будет в базовом классе, а С++ отдает приоритет ближайшему возможному классу, в котором пусть и нет точного совпадения типа, но возможно неявное приведение типа.

Просьба проверить результаты на последних С++ компиляторах и если разница подтвердится, то желательно в целях унификации решить в пользу С++.

 
ozhiganov:
полный текст отправил личным сообщением
Спасибо, будем разбираться.
 

Конструктор копирования и оператор присваивания вообще планируются хоть в каком-то будущем???

базовый класс  A 15 полей, от него образовано два потомка B и С - у каждого еще по +5 полей.

А дальше квест на 20 минут.

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

A100, 2014.08.29 16:28

Ошибка при выводе на посредством Print(...)

void OnStart()
{
        const int n = 300;
        Print( "n=", n );
        for ( int i = 0; i < n; i++ )
        {
                Print( i );
                if ( i == 0 )
                        Sleep( 2000 );
        }
}

при печати вначале пропускает часть вывода от 1 до 53 (каждый раз разную часть - нет четкой закономерности), иногда пропуски посередине

 

далее печатает до 299 без пропусков

Если у кого есть время попробуйте пожалуйста запустить и если будут пропуски при печати - написать. Если пропусков нет - попробуйте увеличить n (у меня пропуски начались при n >= 300) и/или убрать

        if ( i == 0 )
                Sleep( 2000 );

По заявке #1060016 | 2014.08.29 16:30 https://www.mql5.com/ru/users/A100/servicedesk/closed/14774

Возник вопрос "А как информировать о пропуске печати?" - Самый простой вариант - вместо пропущенных строк - одиночная строка с многоточием

 

Видя такую строку пользователь понимает, что имели место пропуски и необходимо обратиться к .log файлу (номера строк не нужны - просто для примера)
 
A100:

Тут в процессе разбора предыдущего примера выяснилось принципиальное различие между MQL и C++

в MQL(build 978) результат: 2 (вызывается С::g), а в С++ результат: 3 (вызывается D::g)

Получается, что MQL отдает приоритет точному совпадению типа аргумента, даже если оно будет в базовом классе, а С++ отдает приоритет ближайшему возможному классу, в котором пусть и нет точного совпадения типа, но возможно неявное приведение типа.

Просьба проверить результаты на последних С++ компиляторах и если разница подтвердится, то желательно в целях унификации решить в пользу С++.

Всё правильно. Приоритет отдаётся точному совпадению. И это действительно правильно

Зачем нужна такая унификация? Унифиикация обработки неправильно спроектированных программ

 
ALXIMIKS:

Конструктор копирования и оператор присваивания вообще планируются хоть в каком-то будущем???

базовый класс  A 15 полей, от него образовано два потомка B и С - у каждого еще по +5 полей.

А дальше квест на 20 минут.

Да, делать будем, но в ближайших планах этого пока нет.
 
stringo:

Всё правильно. Приоритет отдаётся точному совпадению. И это действительно правильно

Зачем нужна такая унификация? Унифиикация обработки неправильно спроектированных программ

Унификация нужна, чтобы один и тот же код работал одинаково с С++ и MQL. В С++ такой порядок неспроста (!) сделан (в ином случае на каком то этапе возникают неоднозначности). Первоначально я подумал, что у С++ компилятора нелогичность и/или даже ошибка, но сейчас склоняюсь к тому, что есть объективные причины такого подхода.  Вот пример на MQL, который показывает, что полное совпадение у X:: g, а вызывается все равно Y::g - как в С++, что противоречит предыдущему примеру https://www.mql5.com/ru/forum/1111/page1223#comment_1074757

class A {};
class B : public A {};
class C : public B {};
class X {
public:
        virtual int g( C* c1, C* c2 ) { return ( 1 ); } //полное совпадение здесь
        virtual int g( C* c,  B* b )  { return ( 2 ); }
};
class Y : public C { //здесь ошибся, должно быть public : X
public:
        virtual int g( A* a, B* b ) { return ( 3 ); }
};
void OnStart()
{
        C* c = new C;
        Y* y = new Y;
        Print( y.g( c, c ));
}

Результат: 3

Получается, что у C++ "нелогичный", но однозначный порядок, а у MQL - случайный порядок - при точном совпадении типов в одном случае вызывается базовый класс, а в другом - производный

 
A100:

Унификация нужна, чтобы один и тот же код работал одинаково с С++ и MQL. В С++ такой порядок неспроста (!) сделан. Первоначально я подумал, что у С++ компилятора нелогичность и/или даже ошибка, но сейчас склоняюсь к тому, что есть объективные причины такого подхода.  Вот пример на MQL, который показывает, что полное совпадение у X:: g, а вызывается все равно Y::g - как в С++, что противоречит предыдущему примеру

Результат: 3

Получается, что у C++ "нелогичный", но однозначный порядок, а у MQL - случайный порядок - при точном совпадении типов в одном случае вызывается базовый класс - в другом производный

О какой конкретно реализации C++ Вы говорите? Насколько эта реализация соответствует стандарту С++. Что сказано в стандарте С++ про порядок выбора перегруженных функций?

На самом деле, описываемая Вами перегрузка функций является следствием неправильного проектирования.

Портирование исходников - это миф. В разных средах С++ одинаково работает только тестовая программа. Реальная программа (речь идёт о тысячах строк кода, имеющих реальное прикладное значение) в разных средах хоть в чём-то, но будет работать по-разному. А об унификации MQL с C++ вообще говорить нечего, растрата семенного фонда...