Errores, fallos, preguntas - página 2639

 
Aleksey Vyazmikin:

¿Por casualidad es necesaria la clave del modo portátil?

¿Todos los terminales se inician manualmente?

A mano, sí, todos lo hacen. Al final, así es como los inicié manualmente.

La tecla de modo portátil no cambia nada en este sentido.

El caso es que MT4 lanza una ventana de autorización y el inicio del programa no se considera completado.

Tienes que usar "start" en el archivo por lotes.

En definitiva, resulta que tengo esto resuelto.

Gracias por su participación.

 
Petros Shatakhtsyan:

Sigues sin entender de qué va esto, probablemente no lees mis posts con atención. Mi llamamiento es para los desarrolladores, no para ti. No necesito tus consejos baratos.

Cálmate y no te preocupes tanto.

Una vez más me convenzo de que las personas con bajo desarrollo cerebral suelen tener poca comprensión del civismo.

Ni siquiera eres capaz de entender lo que te dicen personas con más conocimientos, y eres tan maleducado como un niño de parvulario que ni siquiera ha aprendido a escribir correctamente.

 
Por desgracia, o quizá por suerte, no hago ningún desarrollo directo,
Sin embargo, es el trabajo en los proyectos lo que permite evaluar las capacidades del lenguaje y descubrir sus defectos y fallos...

Anteriormente, al trabajar en proyectos MQL, la información sobre los defectos (bugs) se proporcionaba en el orden de su detección.
Ahora hemos decidido probar un nuevo enfoque: trabajar hasta un defecto de bloqueo y luego proporcionar información sobre todos los defectos detectados.
 
#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;
}
Error muy desagradable en MT5(build 2316), que bloquea el desarrollo posterior.
Creas un objeto complejo envuelto con el tipo interno "C" varias veces, pero resulta ser un tipo de datos muy diferente, tal vez "B", "int", lo que quieras...

Pasé mucho tiempo y esfuerzo para encontrar y entender que el problema no está en el código sino en el compilador MQL. (C++ en línea:https://onlinegdb.com/H1R1fR5ML)
Presumiblemente, el problema está en el trabajo de la caché de la clase de plantilla "main_wrapper" durante la generación de código en tiempo de compilación cuando la clase interna "internal_wrapper" de la clase de plantilla "A" se pasa como parámetro para diferentes tipos de datos (int, B*, B, C).
El primer tipo de datos es creado por la clase de plantilla "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>, dicho tipo de datos se utilizará posteriormente en todos los objetos de la plantilla en el futuro.


A continuación, se presentará otro error con la generación del código de la clase de la plantilla.
 
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;
}

Otro error de MT5(build 2316) con la generación del código de la clase de la plantilla cuando se utiliza la clase interna.
C++ en línea: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;
}

Otro defecto deMT5(build 2316) relacionado con laclase interna es la falta de capacidad para referenciar explícitamente el espacio de nombres global.
C++ en línea:https://onlinegdb.com/H14NF05G8

 
Sergey Dzyublik:
Un error muy desagradable que bloquea el desarrollo posterior.
Creas un objeto complejo envuelto con el tipo interno "C" varias veces, pero resulta ser un tipo de datos muy diferente, tal vez "B", "int", lo que quieras...

Me costó mucho tiempo y esfuerzo encontrar y entender que el problema no está en el código sino en el compilador MQL. (C++ en línea:https://onlinegdb.com/H1R1fR5ML)
Presumiblemente, el problema está en el trabajo de la caché de la clase de plantilla "main_wrapper" durante la generación de código en tiempo de compilación cuando la clase interna "internal_wrapper" de la clase de plantilla "A" se pasa como parámetro para diferentes tipos de datos (int, B*, B, C).
El primer tipo de datos es creado por la clase de plantilla "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>, dicho tipo de datos se utilizará posteriormente en todos los objetos de la plantilla en el futuro.


A continuación, se presentará otro error con la generación del código de la clase de la plantilla.
#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
}
¿Es correcto?
 
Vladimir Simakov:
¿Es esta la forma correcta de hacerlo?

Gracias, efectivamente al introducir un parámetro de plantilla ficticio, en el caso del ejemplo, se obvia el problema.
Sin embargo, en cuanto al proyecto global, es un poco más complicado:la clase interna se aplicó como alternativa a la funcionalidad typedef typename que faltaba para simplificar tanto el proceso de desarrollo como la aplicación de la clase contenedora final.
Puede que merezca la pena esperar a que los desarrolladores lo arreglen.
Como último recurso, todas las dependencias tendrán que ser arrastradas hacia fuera, esperando que no haya más compilaciones exitosas con un comportamiento indefinido en tiempo de ejecución.

 

Para resumir la funcionalidad interna de la clase,
podemos decir claramente que le falta la funcionalidad de la declaración typedef, al menos su forma primitiva, para poder utilizarla correctamente...
Así, en lugar de un código C++ bastante compacto y comprensible:

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;
..............................


Tenemos que construir una valla con #define y la herencia a través de la clase interna:

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
};


Y aquí hay muchos más problemas de lo que puede parecer a primera vista.
Se producen problemas cuando se utiliza #define como declaración typedef:

- no hay manera de pasar el tipo de datos utilizados fuera de la clase (no hay manera de pasar tipos de datos simples en absoluto);
- es necesario controlar constantemente el alcance de #define con el correspondiente par #undef

Problemas al utilizar una clase interna como declaración typedef:
- es posible pasar el tipo de datos de la clase/estructura utilizado fuera de la clase (los tipos de datos simples no pueden pasarse en absoluto);
- la herencia pierde todos los constructores, tienen que ser reescritos manualmente utilizando las firmas de la clase base;
- si la clase en la que se utiliza la declaración typedef tiene una clase base, entonces a través de los espacios de nombres superpuestos no hay manera de utilizar el mismo nombre que la declaración typedef;
- las clases heredan de las clases, las estructuras de las estructuras, esto debe ser constantemente controlado;
 
Debido a la introducción de operadores de asignación por defecto, surgió la necesidad de prohibir la ejecución de asignaciones aleatorias para la clase base.
Para ello, los desarrolladores han añadido "operator= delete".
Sin embargo, no parece lógico que se rompa el enlace de borrado/defecto, porque hay que volver a escribir todo manualmente.
¿Quizás estoy haciendo algo mal?

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;       
}
Razón de la queja: