Erreurs, bugs, questions - page 2661

 
Sergey Dzyublik:

Je m'excuse d'avoir simplifié le code au maximum, introduisant par là même certaines imprécisions, notamment :
- les objets passés à la fonction ont la même taille (code mis à jour) ;
- au lieu d'une sortie muette printf("1");/printf("2") ; on accède en fait directement à l'interface ou aux internes de l'objet, ce qui ne permet pas de mettre en ligne deux algorithmes dans une seule fonction d'appel (code mis à jour).

class C{
public:
   struct A{
   public:
      char aaa;
      
      A (char value = 0) : aaa(value){}
      void set(char value){
         aaa = value; 
      };
      uint Type(){return 0x778F6712;}
      char get(){return aaa;}
      A Get() {return this;}
   };
   
   void test(A&, A& a1, A& a2){
      printf("1");
      a1.aaa = a2.aaa;
   }
   
   template<typename T>
   void test(A& a, T& d1, T& d2){
      if (a.Type()== d1.Type()) test(a,d1.Get(),d2.Get());
      else {
      printf("2");
      d1.set(d2.get());}
   }
};

struct B : public C::A{};


struct D{
private:
   char data;
public:  
   D(char value = 0) : data(value){}
   void set(char value){
      data = value; 
   };
   uint Type(){return 0x308FD7FE;}
   char get(){return data;}
   D Get() {return this;}
};


void OnStart(){
   C c;

   B b;
   D d;
   
   c.test(b, b, b);    // 1      should be: 1
   c.test(b, d, d);    // 2      should be: 2   
}


Ou comme ça :

class C{
public:
   struct A{
   public:
      char aaa;
      
      A (char value = 0) : aaa(value){}
      void set(char value){
         aaa = value; 
      };
      char get(){return aaa;}
      A Get() {return this;}
   };
   
   void test(A&, A& a1, A& a2){
      printf("1");
      a1.aaa = a2.aaa;
   }
   
   template<typename T>
   void test(A& a, T& d1, T& d2){
      printf("2");
      d1.set(d2.get());
   }
};

struct B : public C::A{};


struct D{
private:
   char data;
public:  
   D(char value = 0) : data(value){}
   void set(char value){
      data = value; 
   };
   char get(){return data;}
   D Get() {return this;}
};


void OnStart(){
   C c;

   B b;
   D d;
   
   c.test(b.Get(), b.Get(), b.Get());    // 1      should be: 1
   c.test(b.Get(), d.Get(), d.Get());    // 2      should be: 2   
}
 
Merci pour la solution,
elle n'est pas idéale car elle nécessite des changements dans la structure des objets utilisés et entache la logique, mais elle fonctionne.

Et oui, il est préférable de créer une fonction d'encapsulation au-dessus de test :
.
   template<typename T>
   void test(A& a, T& t1, T& t2){ 
      __test(a, t1.CastToMain(), t2.CastToMain());
   }
Ensuite, recherchez tous les appels dans le projet:
   c.test(b, b.CastToMain(), b.CastToMain());    // 1      should be: 1
   c.test(b, d.CastToMain(), d.CastToMain());    // 2      should be: 2  
En tout cas, merci beaucoup pour votre aide.
 
Sergey Dzyublik:
Merci pour la solution,
Ce n'est pas l'idéal car cela nécessite de modifier la structure des objets utilisés et entache la logique, mais cela fonctionne.

Et oui, il est préférable de créer une fonction wrapper sur test :
plutôt que de rechercher tous les appels dans le projet :

En tout cas, merci beaucoup pour votre aide.

Oui, je suis d'accord.

 

Défauts dans le fonctionnement de la fonction template/class cache :
(non corrigé par MT5(build 2345)) ** Comportement indéfini, vous créez un objet complexe enveloppé avec le type interne "C" plusieurs fois et il s'avère être un type de données complètement différent, peut-être "B", peut-être "int", ce que vous voulez...
(non corrigé par MT5(build 2345)) * Erreur de compilation, bug sur le passage d'un pointeur de fonction comme argument de modèle const ref.
(non corrigé par MT5(build 2345)) * Erreur de compilation, l'objet B<int> peut être créé après l'objet de la classe B<void*>, mais une erreur de compilation se produit si cela est fait avant.


Défauts dans la fonction de modèle/travail de classe :
(non corrigé par MT5(build 2345)) ** Erreur de compilation, bug à l'intérieur d'une fonction template, le pointeur passé dans une opération deconversion de type explicite se comporte comme une classe, sinon comme un pointeur.
(non corrigé par MT5(build 2345)) ** Erreur de compilation, bogue avec la génération de code de classe modèle lors de l'utilisation de classe interne.
(non corrigé par MT5(build 2345)) ** Erreur de compilation, bogue lors de la tentative d'accès à une classe interne pour un paramètre de modèle de fonction de modèle.
(non corrigé par MT5(build 2345)) ** Erreur de compilation : lors de la génération d'une méthode ou d'une classe de modèle, le processus d'"autocomplétion" du paramètre de modèle sort du champ d'application pour entrer dans le code du programme principal.
(non corrigé par MT5(build 2345)) * Erreur de compilation, bogue lié à l'absence de génération automatique du code de la classe du modèle lorsque celle-ci agit comme valeur de retour de la méthode du modèle.
(non corrigé par MT5(build 2345)) * Erreur de compilation, bogue dans la définition de la classe interne - pas de référence à l'espace de noms global lors de la définition d'une classe de base.
(non corrigé par MT5(build 2345)) *(nouveau) Erreur de compilation, bug dans le passage d'une structure interne à une fonction template, letype de données résultant ne peut pas être utilisé comme type de données de base pour une autre structure interne dans la classe template.
(non corrigé par MT5(build 2345)) *(nouveau) Erreur de compilation, un bogue lors de l'appel d'une fonction modèle avec des types d'arguments explicites lorsqu'elle est appelée depuis une fonction non modèle surchargée.


Défauts dans le décalage de la priorité des appels de fonctions surchargées dans MQL par rapport à C++ :
(non corrigé par MT5(build 2345)) *** Erreur de compilation lorsqu'il y a un héritage de classe A <= B <= C <= D et que deux fonctions de surcharge sont implémentées, par exemple, une avec le paramètre A* et une avec le paramètre B*, alors passer dans une telle fonction un objet C* ou D* dans MQL provoque une erreur de compilation "appel ambigu à une fonction surchargée".
(non corrigé par MT5(build 2345)) ** Runtime, incompatibilité de priorité pour les appels de fonctions de modèle surchargées.
(non corrigé par MT5(build 2345)) **(nouveau) Erreur de compilation, la priorité des appels de fonctions template surchargées dépend en fait du type de paramètre template, ce qui théoriquement ne devrait pas affecter le résultat de la compilation.
(non corrigé par MT5(build 2345)) **(new) Compile Error, une erreur de compilation se produit lors de la génération du code d'une fonction template malgré le fait qu'il existe une fonction template surchargée avec une signature appropriée pour les paramètres passés.



Suggestions :
ref- permet de passer des littéraux et des variables temporaires comme arguments const ref à une fonction.
lien- lors dudéplacement de fichiers de projet dans l'onglet Projet, pour les fichiers déplacés qui sont ouverts et dans les onglets ME, pour mettre automatiquement à jour leur chemin d'accès.
link- pour introduire la fonctionnalité de déclaration de typedef dans MQL.
lien- sur la possibilité de forcer la génération de constructeurs de copie et d'opérateurs d'affectation par défaut.

 

Sergey Dzyublik:
Спасибо за вариант решения

le lien est une copie temporaire, donc vous ne pouvez pas modifier la structure

 
Andrei Trukhanovich:
La référence est une copie temporaire, donc vous ne pouvez pas changer la structure.

Vous avez raison dans le cas général...
Mais dans certains cas particuliers, c'est beaucoup plus compliqué et en fait, les structures données sont des itérateurs et ce n'est pas leur contenu qui est modifié, mais les objets auxquels ils font référence.
Le problème est donc résolu dans ce cas particulier et je vous en suis reconnaissant.

 
Bug MT5 (build 2345) plusieurs défauts liés au retour de l'objet "in place created" lorsque l'objet est une classe/structure modèle :

class A{
public:
   A(int, int, int){};  
   A(const A&){}
   A(const A*){}
};

// simple class type
A* test_a_ptr_ptr(){
   return &A(1,2,3);               //OK
};

A test_a_class_class(){
   return A(1,2,3);                //OK
};

A test_a_ptr_class(){
   return &A(1,2,3);               //OK
};


template<typename T>
class B{
public:
   B(int &){}
   B(long){}
   B(int, int, int){};  
   B(const B&){}
   B(const A*){}
};

// template class type
B<A*> test_b_class_class(){
   B<A*> b(1);
   int x = 22;
   
   return B<A*>();              // Compile Error: ambiguous call to overloaded function with the same parameters: "B(long)" and "B(const A*)"
   return B<A*>(1,2,3);         // Compile Error: only one argument is acceptable, argument should be castable to int
   return B<A*>(x);             // Compile Error: argument is passed by value instead of by reference.
   return B<A*>((A*)NULL);      // Compile Error: 'int' - invalid cast operation        
   return B<B<B<long>>>(1);     // Compile Error: OK, template parameter type does not provide any effort on compilation result
   
   return b;
};

B<A*>* test_b_ptr_ptr(){
   B<A*> b(1);
   
   return &B<A*>(1);            // Compile Error: '&' - illegal operation use
   return &b;                 
};


void OnStart (){ 
   // simple class type
   A* a_ptr = test_a_ptr_ptr();
   A a0 = test_a_class_class();
   A a1 = test_a_ptr_class();
   
   // template class type
   B<A*> b0 = test_b_class_class();
   B<A*>* b_ptr = test_b_ptr_ptr();
}
 

Forum sur le trading, les systèmes de trading automatisé et les tests de stratégies de trading

Bugs, bugs, questions

Sergey Dzyublik, 2020.03.01 12:53

class A{
public:
   A(int, int, int){};  
   A(const A&){}
   A(const A*){}
};

// simple class type
A* test_a_ptr_ptr(){
   return &A(1,2,3);               //OK
};

Si je comprends bien, cette fonction renverra le pointeur vers l'objet qui n'existe pas ?

 
fxsaber:

Ai-je bien compris que cette fonction renverra un pointeur vers un objet inexistant ?

Oui, dans cet exemple, la fonction renverra un pointeur vers un objet inexistant.
L'objectif principal de ce code est de montrer qu'il existe une fonctionnalité fonctionnelle pour une classe simple et qu'en même temps, il n'y en a pas pour une classe modèle.

 

J'ai un cas difficile - il n'y a aucune logique à ma disposition.

Il existe une fonction avec ces entrées

int Tree_Calcf(int &arr_List_Buy[],int &arr_List_Sell[],int Vektor_ZZ,int Variant_Tree_Buy=0,int Variant_Tree_Sell=0)
{
int CalcBuy=1;
int CalcSell=1;
//Print("Rez_Tree_Calc=",Rez," - f"," Vektor_ZZ=",Vektor_ZZ," CalcSell=",CalcSell);

if (Vektor_ZZ==1)
{
if(Variant_Tree_Buy==1)
{
                        if(arr_List_Buy[272]< 0.5 && arr_List_Buy[100]< 0.5 && arr_List_Buy[249]< 0.5 && arr_List_Buy[147]< 0.5 && arr_List_Buy[350]< 0.5 && arr_List_Buy[383]< 0.5 && arr_List_Buy[463]< 0.5 && arr_List_Buy[250]< 0.5 && arr_List_Buy[283]< 0.5 && arr_List_Buy[204]< 0.5 && arr_List_Buy[499]< 0.5 && arr_List_Buy[296]< 0.5 && arr_List_Buy[486]< 0.5 && arr_List_Buy[209]< 0.5 && arr_List_Buy[453]< 0.5 && arr_List_Buy[333]< 0.5 && arr_List_Buy[137]< 0.5 && arr_List_Buy[127]< 0.5 && arr_List_Buy[191]< 0.5 && arr_List_Buy[395]< 0.5 && arr_List_Buy[224]< 0.5 && arr_List_Buy[432]< 0.5 && arr_List_Buy[378]< 0.5 && arr_List_Buy[25]< 0.5 && arr_List_Buy[441]< 0.5 && arr_List_Buy[2]< 0.5 && arr_List_Buy[465]< 0.5 && arr_List_Buy[231]< 0.5 && arr_List_Buy[482]< 0.5 && arr_List_Buy[324]< 0.5) CalcBuy=0; //(0.83965634 0.16034366)
//--Вырезана часть аналогичного кода - листья дерева
}

//V03
if(Variant_Tree_Buy==2)
{
//---Вырезан код, он не активируется в момент ошибки}
//--Дерево на базе активации листьев без фильтров
if(Variant_Tree_Buy==3)
{
//---Вырезан код, он не активируется в момент ошибки}
}
//----TreeList_Sell
if(Vektor_ZZ==-1)
{
if(Variant_Tree_Sell==1)
{

                        if(arr_List_Sell[127]< 0.5 && arr_List_Sell[275]< 0.5 && arr_List_Sell[42]< 0.5 && arr_List_Sell[389]< 0.5 && arr_List_Sell[121]< 0.5 && arr_List_Sell[410]< 0.5 && arr_List_Sell[39]< 0.5 && arr_List_Sell[348]< 0.5 && arr_List_Sell[358]< 0.5 && arr_List_Sell[143]< 0.5 && arr_List_Sell[396]< 0.5 && arr_List_Sell[364]< 0.5 && arr_List_Sell[354]< 0.5 && arr_List_Sell[160]< 0.5 && arr_List_Sell[324]< 0.5 && arr_List_Sell[46]< 0.5 && arr_List_Sell[38]< 0.5 && arr_List_Sell[397]< 0.5 && arr_List_Sell[295]< 0.5 && arr_List_Sell[48]< 0.5 && arr_List_Sell[322]< 0.5 && arr_List_Sell[363]< 0.5 && arr_List_Sell[40]< 0.5 && arr_List_Sell[420]< 0.5 && arr_List_Sell[43]< 0.5 && arr_List_Sell[230]< 0.5 && arr_List_Sell[10]< 0.5 && arr_List_Sell[471]< 0.5 && arr_List_Sell[507]< 0.5 && arr_List_Sell[259]< 0.5) CalcSell=0; //(0.78952321 0.21047679)





//--Вырезана часть аналогичного кода - листья дерева
} if(Variant_Tree_Sell==2) { //---Вырезан код, он не активируется в момент ошибки } //--Дерево на базе активации листьев без фильтров if(Variant_Tree_Sell==3) { //---Вырезан код, он не активируется в момент ошибки } } int Rez=0; if(Vektor_ZZ==1)Rez=CalcBuy; if(Vektor_ZZ==-1)Rez=CalcSell; Print("Rez_Tree_Calc=",Rez," - f"," Vektor_ZZ=",Vektor_ZZ," CalcSell=",CalcSell); return Rez; }

Ainsi, cette fonction produit parfois une valeur de 769

2020.03.01 15:54:23.500 Core 1  2019.11.13 22:57:00   Rez_Tree_Calc=769 - f Vektor_ZZ=-1 CalcSell=769

Si vous décommentez la première impression

//Print("Rez_Tree_Calc=",Rez," - f"," Vektor_ZZ=",Vektor_ZZ," CalcSell=",CalcSell);

alors il donne la valeur correcte.

Si vous tronquez la fonction en supprimant uniquement le code qui n'est pas activé au moment où la fonction est appelée au moment de l'erreur, il n'y a pas non plus d'erreur.

Manifestement une erreur de compilateur - développeurs, à qui envoyer la fonction complète, car elle ne tient pas sur le forum.