Fehler, Irrtümer, Fragen - Seite 2639

 
Aleksey Vyazmikin:

Ist der Schlüssel für den portablen Modus zufällig erforderlich?

Werden alle Terminals manuell gestartet?

Von Hand, ja, das tun sie alle. Letztendlich habe ich sie auf diese Weise manuell gestartet.

Die Taste für den portablen Modus ändert in dieser Hinsicht nichts.

Das Problem ist, dass MT4 ein Autorisierungsfenster ausgibt und der Programmstart nicht als abgeschlossen betrachtet wird.

Sie müssen "start" in der Batch-Datei verwenden.

Alles in allem stelle ich fest, dass ich die Sache gut im Griff habe.

Vielen Dank für Ihre Teilnahme!

 
Petros Shatakhtsyan:

Wenn Sie immer noch nicht verstehen, worum es hier geht, lesen Sie wahrscheinlich meine Beiträge nicht aufmerksam. Mein Appell richtet sich an die Entwickler, nicht an Sie. Ich brauche Ihre billigen Ratschläge nicht.

Beruhigen Sie sich und machen Sie sich nicht so viele Sorgen.

Einmal mehr bin ich davon überzeugt, dass Menschen mit einer geringen Gehirnentwicklung in der Regel wenig Verständnis für Höflichkeit haben.

Sie können nicht einmal verstehen, was man Ihnen sagt, und Sie sind so unhöflich wie ein Kindergartenkind, das noch nicht einmal gelernt hat, richtig zu schreiben.

 
Leider, oder vielleicht auch zum Glück, mache ich keine direkte Entwicklung,
Es ist jedoch die Arbeit an den Projekten, die es Ihnen ermöglicht, die Fähigkeiten der Sprache zu bewerten und ihre Mängel und Bugs zu entdecken...

Früher wurden bei der Arbeit an MQL-Projekten die Informationen über Fehler (Bugs) in der Reihenfolge ihrer Entdeckung bereitgestellt.
Jetzt haben wir beschlossen, einen neuen Ansatz zu versuchen - wir arbeiten uns bis zu einem blockierenden Fehler vor und stellen dann Informationen über alle gefundenen Fehler zur Verfügung.
 
#ifdef __cplusplus
   #include <iostream>
#endif 

#define  PRINT(x) ; Print(#x, ":", string(x))


template<typename T>
class main_wrapper{
public:
   T data;
};

template<typename T>
class external_wrapper{
public:
   T data;
};

template<typename T>
class A{
public:
   class internal_wrapper : public external_wrapper<T> {};
   
   main_wrapper<internal_wrapper> internal_wrapper_0;
   main_wrapper<external_wrapper<T>> external_wrapper_0;
   
   A(){
        main_wrapper<internal_wrapper> internal_wrapper_1;
        main_wrapper<external_wrapper<T>> external_wrapper_1;
   
        #ifdef __MQL5__
            PRINT(__FUNCSIG__);
            PRINT(typename(internal_wrapper_0.data.data));      // (Bug) int  int
            PRINT(typename(external_wrapper_0.data.data));      // (OK)  int  B*
            PRINT(typename(internal_wrapper_1.data.data));      // (Bug) int  int
            PRINT(typename(external_wrapper_1.data.data));      // (OK)  int  B*
        #endif
   }
};

class B{
   char data[10];
};

class C{
   char data[1000];
};


void OnStart()
{ 
   A<int> val_int;
   A<B*> val_ptr;
   
   printf("%d\n", sizeof(main_wrapper<A<B>::internal_wrapper>));  // (Bug) 36  //sizeof(main_wrapper<A<int>::internal_wrapper>) is used
   printf("%d\n", sizeof(main_wrapper<A<C>::internal_wrapper>));  // (Bug) 36  //sizeof(main_wrapper<A<int>::internal_wrapper>) is used
}

int main(){
   OnStart();
   return 1;
}
Sehr unangenehmer MT5(build 2316) Bug, der die weitere Entwicklung blockiert.
Sie erstellen mehrmals ein komplexes umhülltes Objekt mit dem internen Typ "C", aber es stellt sich heraus, dass es ein ganz anderer Datentyp ist, vielleicht "B", "int", was auch immer Sie wollen...

Ich habe viel Zeit und Mühe investiert, um herauszufinden und zu verstehen, dass das Problem nicht im Code, sondern im MQL-Compiler liegt. (C++ online:https://onlinegdb.com/H1R1fR5ML)
Vermutlich liegt das Problem in der Arbeit des Zwischenspeichers der Template-Klasse "main_wrapper" während der Codegenerierung zur Kompilierungszeit, wenn die interne Klasse "internal_wrapper" aus der Template-Klasse "A" als Parameter für verschiedene Datentypen (int, B*, B, C) übergeben wird.
Welcher erste Datentyp von der Template-Klasse "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper> erzeugt wird, dieser Datentyp wird in Zukunft in allen Objekten des Templates weiterverwendet werden.


Ein weiterer Fehler bei der Generierung des Codes der Vorlagenklasse wird weiter unten beschrieben.
 
class A{
public:
   class B{};
};

template<typename T>
class wrapper{
public:
   T data;
};

template<typename T>
class wrapped_B{
public:
   A::B data;
};
   
void OnStart()
{ 
   A::B a;                // OK
   wrapper<A::B> b0;      // 'B' - unexpected token, probably type is missing?  'data' - semicolon expected     
   
   wrapped_B<A::B> b2;    // OK
   
   class local_B : public A::B{};
   wrapper<local_B> b1;   // OK
}


int main(){
   OnStart();
   return 0;
}

Ein weiterer MT5(build 2316) Fehler bei der Generierung von Template-Klassencode bei Verwendung einer internen Klasse.
C++ online:https://onlinegdb.com/HJkKXAqMU

 
template<typename T>
class type_wrapper{
    T data;
};

template<typename T>
class A{
   class type_wrapper : public :: type_wrapper<T>{}; // '::' - syntax error      
};

void OnStart()
{ 
   A<int> a;
}


int main(){
   OnStart();
   return 0;
}

Ein weiterer Fehler inMT5 (Build 2316), der mit derinternen Klasse zusammenhängt, ist die fehlende Möglichkeit, explizit auf den globalen Namespace zu verweisen.
C++ online:https://onlinegdb.com/H14NF05G8

 
Sergey Dzyublik:
Ein sehr unangenehmer Fehler, der die weitere Entwicklung blockiert.
Sie erstellen mehrmals ein komplexes umhülltes Objekt mit dem internen Typ "C", aber es stellt sich heraus, dass es ein ganz anderer Datentyp ist, vielleicht "B", "int", was auch immer Sie wollen...

Es hat mich viel Zeit und Mühe gekostet, herauszufinden und zu verstehen, dass das Problem nicht im Code, sondern im MQL-Compiler liegt. (C++ online:https://onlinegdb.com/H1R1fR5ML)
Vermutlich liegt das Problem in der Arbeit des Zwischenspeichers der Template-Klasse "main_wrapper" während der Codegenerierung zur Kompilierungszeit, wenn die interne Klasse "internal_wrapper" aus der Template-Klasse "A" als Parameter für verschiedene Datentypen (int, B*, B, C) übergeben wird.
Welcher erste Datentyp von der Template-Klasse "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper> erzeugt wird, dieser Datentyp wird in Zukunft in allen Objekten des Templates weiterverwendet werden.


Ein weiterer Fehler bei der Generierung des Codes der Vorlagenklasse wird weiter unten beschrieben.
#ifdef __cplusplus
   #include <iostream>
#endif 

#define  PRINT(x) ; Print(#x, ":", string(x))


template<typename T>
class main_wrapper{
public:
   T data;
};

template<typename T>
class external_wrapper{
public:
   T data;
};

template<typename T>
class A{
public:
   template<typename T1>
   class internal_wrapper : public external_wrapper<T1> {};
   
   main_wrapper<internal_wrapper<T>> internal_wrapper_0;
   main_wrapper<external_wrapper<T>> external_wrapper_0;
   
   A(){
        main_wrapper<internal_wrapper<T>> internal_wrapper_1;
        main_wrapper<external_wrapper<T>> external_wrapper_1;
   
        #ifdef __MQL5__
            PRINT(__FUNCSIG__);
            PRINT(typename(internal_wrapper_0.data.data));      // (Bug) int  int
            PRINT(typename(external_wrapper_0.data.data));      // (OK)  int  B*
            PRINT(typename(internal_wrapper_1.data.data));      // (Bug) int  int
            PRINT(typename(external_wrapper_1.data.data));      // (OK)  int  B*
        #endif
   }
};

class B{
   char data[10];
};

class C{
   char data[1000];
};


void OnStart()
{ 
   A<int> val_int;
   A<B*> val_ptr;
   
   printf("%d\n", sizeof(main_wrapper<A<B>::internal_wrapper<B>>));  // (Bug) 36  //sizeof(main_wrapper<A<int>::internal_wrapper>) is used
   printf("%d\n", sizeof(main_wrapper<A<C>::internal_wrapper<C>>));  // (Bug) 36  //sizeof(main_wrapper<A<int>::internal_wrapper>) is used
}
Ist das richtig?
 
Vladimir Simakov:
Ist das der richtige Weg?

Danke, in der Tat umgeht die Einführung eines Dummy-Parameters für die Vorlage im Fall des Beispiels das Problem.
Bei dem globalen Projekt ist es jedoch etwas komplizierter:Die interne Klasse wurde als Alternative zur fehlenden typedef typename-Funktionalität verwendet, um sowohl den Entwicklungsprozess als auch die Anwendung der endgültigen Containerklasse zu vereinfachen.
Es könnte sich lohnen, auf eine Korrektur durch die Entwickler zu warten.
Als letztes Mittel müssen alle Abhängigkeiten nach außen gezogen werden, in der Hoffnung, dass keine weitere erfolgreiche Kompilierung mit undefiniertem Verhalten zur Laufzeit erfolgt.

 

Um die internen Funktionen der Klasse zusammenzufassen,
können wir eindeutig sagen, dass es an der Funktionalität der Typdeklaration fehlt, zumindest an ihrer primitiven Form, um sie richtig zu nutzen...
Anstelle von kompaktem und klarem C++-Code:

template <class _Tp, class _Allocator>
class vector
    : private __vector_base<_Tp, _Allocator>
{
private:
    typedef __vector_base<_Tp, _Allocator>           __base;
public:
    typedef vector                                   __self;
    typedef _Tp                                      value_type;
    typedef _Allocator                               allocator_type;
    typedef typename __base::__alloc_traits          __alloc_traits;
    typedef typename __base::reference               reference;
    typedef typename __base::const_reference         const_reference;
    typedef typename __base::size_type               size_type;
..............................


Wir müssen einen Zaun mit #define und Vererbung durch die interne Klasse bauen:

template<typename _Tp, typename _Allocator>
class __vector_base{
public:
   class allocator_type    : public _Allocator{}; 
   
protected:
   #define  value_type          _Tp
   #define  size_type           DEFAULT_SIZE_TYPE
   #define  difference_type     size_type
   
   struct pointer          : public allocator_type::pointer{};
   struct iterator         : public allocator_type::pointer{};
............................

   #undef  value_type
   #undef  size_type
   #undef  difference_type
};


Und hier gibt es viel mehr Probleme, als es auf den ersten Blick scheinen mag.
Probleme treten auf, wenn #define als typedef-Deklaration verwendet wird:

- es gibt keine Möglichkeit, den Typ der verwendeten Daten außerhalb der Klasse zu übergeben (es gibt überhaupt keine Möglichkeit, einfache Datentypen zu übergeben);
- ist es notwendig, den Geltungsbereich von #define ständig mit dem entsprechenden #undef-Paar zu kontrollieren

Probleme bei der Verwendung einer internen Klasse als typedef-Deklaration:
- es ist möglich, Klasse/Struktur-Datentypen, die außerhalb der Klasse verwendet werden, zu übergeben (einfache Datentypen können überhaupt nicht übergeben werden);
- durch Vererbung gehen alle Konstruktoren verloren, sie müssen manuell mit Signaturen aus der Basisklasse neu geschrieben werden;
- wenn die Klasse, in der die typedef-Deklaration verwendet wird, eine Basisklasse hat, dann gibt es durch überlappende Namensräume keine Möglichkeit, den gleichen Namen wie die typedef-Deklaration zu verwenden;
- Klassen erben von Klassen, Strukturen von Strukturen, dies muss ständig kontrolliert werden;
 
Durch die Einführung von Standard-Zuweisungsoperatoren ergab sich die Notwendigkeit, die zufällige Ausführung von Zuweisungen für die Basisklasse zu verbieten.
Die Entwickler haben zu diesem Zweck "operator= delete" hinzugefügt.
Es erscheint jedoch nicht logisch, die Verknüpfung "Löschen/Standard" zu unterbrechen, weil dann alles wieder manuell geschrieben werden muss.
Vielleicht mache ich etwas falsch?

class Base{
    char base_data[100];
};

template<typename T>
class A : public Base{
   int data_1;
   int data_2;
   int data_3;
   int data_4;
   int data_5;
   int data_6;
   int data_7;
   int data_8;
   int data_9;
   
   char arr_1[];
   char arr_2[];
public:    
   // MQL
   A* operator=(A &obj){
      data_1 = obj.data_1; 
      data_2 = obj.data_2; 
      data_3 = obj.data_3; 
      data_4 = obj.data_4; 
      data_5 = obj.data_5; 
      data_6 = obj.data_6; 
      data_7 = obj.data_7; 
      data_8 = obj.data_8; 
      data_9 = obj.data_9; 
      
      ArrayCopy(arr_1, obj.arr_1);
      ArrayCopy(arr_2, obj.arr_2); 
      
      (Base)this = obj;
      return &this;
   };
   
   // C++
   // A& operator=(A &) = default;
    
   template<typename TT>
   A* operator=(A<TT> &) = delete;
};

void OnStart()
{ 
   A<int> a;
   A<int> b;
   
   A<double> c;
   
   a = b;      
   //a = c;       
}