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

 

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

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

Koldun Zloy, 2024.01.18 16:33

Для однозначности нужно просто запретить неявное разыменование указателя при создании указателя.

Так же как для ссылки в C++.


Похоже, проблема одной природы.

class A {};

void f(A&) {}
void g(A*) {}

void OnStart()
{
  f(new A); // Вроде, здесь должна быть ошибка.
  g(new A);
}
 
fxsaber #:

Похоже, проблема одной природы.

Думаю, не должно быть там ошибки. Там все законно.

Указатели объектов (ссылка)

void OnStart()
  {
//--- объявим указатель на объект и создадим его с помощью оператора 'new'
   Foo *foo2=new Foo("foo2");
//--- вариант передачи указателя на объект по ссылке
   PrintObject(foo2); // указатель на объект автоматически преобразуется компилятором
  }
//+------------------------------------------------------------------+
//|  Объекты всегда передаются по ссылке                             |
//+------------------------------------------------------------------+
void PrintObject(Foo &object)
  {
   Print(__FUNCTION__,": ",object.m_id," Object name=",object.m_name);
  }

Ну а если программист решил потерять таким образом указатель, то кто ж ему виноват😄

 
Valeriy Yastremskiy #:

Что то опять форматирование слетело. Нижняя строчка поста "в карман / нарушение \ ответить" была справа, стала слева. Стало хуже читать на компе. вин7 хром.


Всё исправилось.
 
Vladislav Boyko #:

Думаю, не должно быть там ошибки. Там все законно.

Ну а если программист решил потерять таким образом указатель, то кто ж ему виноват😄

В Вашем примере объект в принципе можно удалить.

А разрешать создавать временный объект при помощи new нет никакого смысла, так как его в принципе удалить невозможно.

 
Vladislav Boyko #:

Там все законно.

class A {};

void OnStart()
{
  A* Pointer = NULL;
  A Object;
  
  Object = Pointer;
}

Ну ерунда же.

 

(Автоматический русский перевод применен из оригинального английского текста)

Не знаю, сообщалось ли об этом раньше или нет, но на английском форуме сообщалось об ошибке использования функции iCustom() при использовании "групп ввода" в пользовательских индикаторах.

Другими словами, когда в пользовательском индикаторе используется «входная группа», ее необходимо включить во входные параметры функции iCustom() .

Я сам подтвердил ошибку и предложил доказательство этой ошибки...

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

Обнаружена ошибка с группой ввода и iCustom().

Фернандо Каррейру , 2024.01.24 14:20

Вот моя собственная интерпретация и тестирование...

Простой индикатор:

 #property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0

input int       i_nNumber = 99 ;
input double    i_dbValue = 99.5 ;

int OnInit () {
   PrintFormat ( "%s (%d,%.2f)" , __FILE__ , i_nNumber, i_dbValue );
   return INIT_SUCCEEDED ;
};

int OnCalculate ( const int rates_total, const int prev_calculated, const int begin, const double & price[] ) {
   return rates_total;
};

Индикатор группы:

 #property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0

input group     "Group 1"
input int       i_nNumber = 99 ;
input group     "Group 2"
input double    i_dbValue = 99.5 ;

int OnInit () {
   PrintFormat ( "%s (%d,%.2f)" , __FILE__ , i_nNumber, i_dbValue );
   return INIT_SUCCEEDED ;
};

int OnCalculate ( const int rates_total, const int prev_calculated, const int begin, const double & price[] ) {
   return rates_total;
};

Тестирование советника с различными комбинациями...

 int hIndicatorSimple = INVALID_HANDLE ,
    hIndicatorGroup1 = INVALID_HANDLE ,
    hIndicatorGroup2 = INVALID_HANDLE ,
    hIndicatorGroup3 = INVALID_HANDLE ,
    hIndicatorGroup4 = INVALID_HANDLE ;

int OnInit () {
   ResetLastError (); hIndicatorSimple = iCustom ( _Symbol , _Period , "Indicator_simple" ,     0 ,     0.5 ); int errSimple = _LastError ;
   ResetLastError (); hIndicatorGroup1 = iCustom ( _Symbol , _Period , "Indicator_group" ,       1 ,     1.5 ); int errGroup1 = _LastError ;
   ResetLastError (); hIndicatorGroup2 = iCustom ( _Symbol , _Period , "Indicator_group" ,       2 , "" , 2.5 ); int errGroup2 = _LastError ;
   ResetLastError (); hIndicatorGroup3 = iCustom ( _Symbol , _Period , "Indicator_group" ,   "" , 3 ,     3.5 ); int errGroup3 = _LastError ;
   ResetLastError (); hIndicatorGroup4 = iCustom ( _Symbol , _Period , "Indicator_group" ,   "" , 4 , "" , 4.5 ); int errGroup4 = _LastError ;
   PrintFormat ( "Simple: %d (%d), Group1: %d (%d), Group2: %d (%d), Group3: %d (%d), Group4: %d (%d)" ,
      hIndicatorSimple, errSimple,
      hIndicatorGroup1, errGroup1, 
      hIndicatorGroup2, errGroup2,
      hIndicatorGroup3, errGroup3,
      hIndicatorGroup4, errGroup4 );
   return INIT_SUCCEEDED ;
};

void OnDeinit ( const int reason ) {
   IndicatorRelease ( hIndicatorSimple );      
   IndicatorRelease ( hIndicatorGroup1 );
   IndicatorRelease ( hIndicatorGroup2 );
   IndicatorRelease ( hIndicatorGroup3 );
   IndicatorRelease ( hIndicatorGroup4 );
};

void OnTick () {
   ExpertRemove ();
};

А результаты из журнала Экспертов ...

2024.01.24 13:10:46.512 expert_group (EURUSD,H1)        cannot load custom indicator 'Indicator_group' [4002]
2024.01.24 13:10:46.512 expert_group (EURUSD,H1)        Simple: 10 (0), Group1: 11 (0), Group2: -1 (4002), Group3: 12 (0), Group4: 13 (0)
2024.01.24 13:10:46.516 indicator_group (EURUSD,H1)     indicator_group.mq5 (4,4.50)
2024.01.24 13:10:46.518 indicator_group (EURUSD,H1)     indicator_group.mq5 (3,99.50)
2024.01.24 13:10:46.520 indicator_group (EURUSD,H1)     indicator_group.mq5 (1,99.50)
2024.01.24 13:10:46.522 indicator_simple (EURUSD,H1)    indicator_simple.mq5 (0,0.50)
2024.01.24 13:10:46.637 expert_group (EURUSD,H1)        ExpertRemove() function called

Заключение ...

Группы ввода должны быть включены в вызов функции iCustom() , чтобы она работала правильно, вопреки тому, что может подразумеваться в документации.

Я бы классифицировал это как ошибку, но, учитывая склонность MetaQuotes отрицать определенные ошибки, они, скорее всего, не будут ее исправлять и классифицируют это как недосмотр в документации.


Файлы примеров прилагаю...

(Automated Russian translation applied from original English text)

I don't know if this has been reported before or not, but on the English forum a bug was reported about the use of the iCustom() function when using "input groups" in the custom indicators.

In other words, when a "input group" is used in a custom indicator, it has to be included in the input parameters of the iCustom() function.

I have confirmed the bug myself and offered proof of this bug ...

Forum on trading, automated trading systems and testing trading strategies

Bug found with input group and iCustom()

Fernando Carreiro, 2024.01.24 14:20

Here is my own rendition and testing ...

Simple indicator:

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0

input int      i_nNumber = 99;
input double   i_dbValue = 99.5;

int OnInit() {
   PrintFormat( "%s (%d,%.2f)", __FILE__, i_nNumber, i_dbValue );
   return INIT_SUCCEEDED;
};

int OnCalculate( const int rates_total, const int prev_calculated, const int begin, const double& price[] ) {
   return rates_total;
};

Group Indicator:

#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0

input group    "Group 1"
input int      i_nNumber = 99;
input group    "Group 2"
input double   i_dbValue = 99.5;

int OnInit() {
   PrintFormat( "%s (%d,%.2f)", __FILE__, i_nNumber, i_dbValue );
   return INIT_SUCCEEDED;
};

int OnCalculate( const int rates_total, const int prev_calculated, const int begin, const double& price[] ) {
   return rates_total;
};

Testing EA with various combinations ...

int hIndicatorSimple = INVALID_HANDLE,
    hIndicatorGroup1 = INVALID_HANDLE,
    hIndicatorGroup2 = INVALID_HANDLE,
    hIndicatorGroup3 = INVALID_HANDLE,
    hIndicatorGroup4 = INVALID_HANDLE;

int OnInit() {
   ResetLastError(); hIndicatorSimple = iCustom( _Symbol, _Period, "Indicator_simple",     0,     0.5 ); int errSimple = _LastError;
   ResetLastError(); hIndicatorGroup1 = iCustom( _Symbol, _Period, "Indicator_group",      1,     1.5 ); int errGroup1 = _LastError;
   ResetLastError(); hIndicatorGroup2 = iCustom( _Symbol, _Period, "Indicator_group",      2, "", 2.5 ); int errGroup2 = _LastError;
   ResetLastError(); hIndicatorGroup3 = iCustom( _Symbol, _Period, "Indicator_group",  "", 3,     3.5 ); int errGroup3 = _LastError;
   ResetLastError(); hIndicatorGroup4 = iCustom( _Symbol, _Period, "Indicator_group",  "", 4, "", 4.5 ); int errGroup4 = _LastError;
   PrintFormat( "Simple: %d (%d), Group1: %d (%d), Group2: %d (%d), Group3: %d (%d), Group4: %d (%d)",
      hIndicatorSimple, errSimple,
      hIndicatorGroup1, errGroup1, 
      hIndicatorGroup2, errGroup2,
      hIndicatorGroup3, errGroup3,
      hIndicatorGroup4, errGroup4 );
   return INIT_SUCCEEDED;
};

void OnDeinit( const int reason ) {
   IndicatorRelease( hIndicatorSimple );      
   IndicatorRelease( hIndicatorGroup1 );
   IndicatorRelease( hIndicatorGroup2 );
   IndicatorRelease( hIndicatorGroup3 );
   IndicatorRelease( hIndicatorGroup4 );
};

void OnTick() {
   ExpertRemove();
};

And the results from the Experts log ...

2024.01.24 13:10:46.512 expert_group (EURUSD,H1)        cannot load custom indicator 'Indicator_group' [4002]
2024.01.24 13:10:46.512 expert_group (EURUSD,H1)        Simple: 10 (0), Group1: 11 (0), Group2: -1 (4002), Group3: 12 (0), Group4: 13 (0)
2024.01.24 13:10:46.516 indicator_group (EURUSD,H1)     indicator_group.mq5 (4,4.50)
2024.01.24 13:10:46.518 indicator_group (EURUSD,H1)     indicator_group.mq5 (3,99.50)
2024.01.24 13:10:46.520 indicator_group (EURUSD,H1)     indicator_group.mq5 (1,99.50)
2024.01.24 13:10:46.522 indicator_simple (EURUSD,H1)    indicator_simple.mq5 (0,0.50)
2024.01.24 13:10:46.637 expert_group (EURUSD,H1)        ExpertRemove() function called

Conclusion ...

The Input Groups have to be included in the call to iCustom() function for it to work correctly, contrary to what the documentation may imply.

I would classify this as a bug, but given the propensity for MetaQuotes to deny certain bugs, they will most probably not fix it and classify it an oversight in the documentation.


Sample files have been attached ...

Файлы:
 
fxsaber #:

Ну ерунда же.

Совсем ерунда.

class A {};

void OnStart()
{
  A* Pointer = NULL;
  A Object;
  
  Object = Pointer;
  Pointer = Object;
}
 
fxsaber #:

Совсем ерунда.

всё ок...

указатель в mql это не указатель в C++. Вообще принципиально разные вещи и ближе к syntax sugar

вас попутывает A1-- :-)

 
Fernando Carreiro #:
input group     "Group 1"

Почему вы считаете это ошибкой?

Это давно уже так.

Если запустить скрипт из справки к IndicatorParameters, он сразу показывает, что input group является полноценным параметром индикатора, который нужно передавать во входные параметры функции iCustom()


Short name Round_Levels, type IND_CUSTOM
parameter 0: type=TYPE_STRING, long_value=0, double_value=0,string_value=Indicators\Круглые уровни\Round_Levels.ex5
parameter 1: type=TYPE_INT, long_value=5, double_value=0,string_value=(null)
parameter 2: type=TYPE_INT, long_value=0, double_value=0,string_value=(null)
parameter 3: type=TYPE_BOOL, long_value=1, double_value=0,string_value=(null)
parameter 4: type=TYPE_UINT, long_value=12180223, double_value=0,string_value=(null)

и так далее...


 
Koldun Zloy #:
А разрешать создавать временный объект при помощи new нет никакого смысла, так как его в принципе удалить невозможно.

При большом желании удалить то можно

class A {};

void f(A& a) { delete GetPointer(a); }

void OnStart()
{
  f(new A);
}

Другое дело, что у программиста не должно возникать желания использовать new в подобном месте.

Warning лишним бы не был, я согласен.

Причина обращения: