Erros, bugs, perguntas - página 2639

 
Aleksey Vyazmikin:

A chave do modo portátil é necessária por acaso?

Todos os terminais começam manualmente?

À mão, sim, todos eles o fazem. No final, foi assim que os comecei manualmente.

A chave do modo portátil não muda nada a este respeito.

A questão é que o MT4 lança uma janela de autorização e o início do programa não é considerado concluído.

Tem de usar "iniciar" no ficheiro de lote.

No fim de contas, acontece que já tenho este planeado.

Obrigado pela vossa participação!

 
Petros Shatakhtsyan:

Ainda não compreende do que se trata, provavelmente não leu atentamente as minhas mensagens. O meu apelo é para os criadores, não para si. Não preciso dos vossos conselhos baratos.

Acalme-se e não se preocupe tanto.

Mais uma vez estou convencido de que as pessoas com baixo desenvolvimento cerebral geralmente têm pouca compreensão da civilidade.

Nem sequer consegue compreender o que lhe é dito por pessoas mais conhecedoras, e é tão rude como uma criança do jardim-de-infância que nem sequer aprendeu a escrever correctamente.

 
Infelizmente, ou talvez felizmente, eu não faço nenhum desenvolvimento directo,
No entanto, é o trabalho nos projectos que lhe permite avaliar as capacidades da língua e descobrir os seus defeitos e bugs...

Anteriormente, ao trabalhar em projectos MQL, a informação sobre defeitos (bugs) era fornecida na ordem da sua detecção.
Agora decidimos tentar uma nova abordagem - trabalhar até um defeito de bloqueio e depois fornecer informações sobre todos os defeitos 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;
}
Bug MT5(build 2316) muito desagradável, bloqueando um maior desenvolvimento.
Cria-se várias vezes um objecto complexo embrulhado com tipo interno "C", mas acaba por ser um tipo de dados bastante diferente, talvez "B", "int", o que se quiser...

Demorei muito tempo e esforço para encontrar e compreender que o problema não está no código mas sim no compilador MQL. (C++ online:https://onlinegdb.com/H1R1fR5ML)
Presumivelmente, o problema está no trabalho da cache da classe template "main_wrapper" durante a geração do código no momento da compilação, quando a classe interna "internal_wrapper" da classe template "A" é passada como parâmetro para diferentes tipos de dados (int, B*, B, C).
Que primeiro tipo de dados é criado pela classe de modelo "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>, tal tipo de dados será mais tarde utilizado em todos os objectos do modelo no futuro.


Um outro bug com a geração do código da classe modelo será fornecido abaixo.
 
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;
}

Outro bug MT5(build 2316) com geração de código de classe modelo quando se usa a classe interna.
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;
}

Outro defeitoMT5(build 2316) relacionado com aclasse interna é a falta de capacidade de referenciar explicitamente o namespace global.
C++ online:https://onlinegdb.com/H14NF05G8

 
Sergey Dzyublik:
Um insecto muito desagradável que bloqueia um maior desenvolvimento.
Cria-se um objecto complexo embrulhado com tipo interno "C" várias vezes, mas acaba por ser um tipo de dados bastante diferente, talvez "B", "int", o que se quiser...

Gastei muito tempo e esforço para encontrar e compreender que o problema não está no código mas sim no compilador MQL. (C++ online:https://onlinegdb.com/H1R1fR5ML)
Presumivelmente, o problema está no trabalho da cache da classe template "main_wrapper" durante a geração do código no momento da compilação, quando a classe interna "internal_wrapper" da classe template "A" é passada como parâmetro para diferentes tipos de dados (int, B*, B, C).
Que primeiro tipo de dados é criado pela classe de modelo "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>, tal tipo de dados será mais tarde utilizado em todos os objectos do modelo no futuro.


Um outro bug com a geração do código da classe modelo será fornecido abaixo.
#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
}
É correcto?
 
Vladimir Simakov:
Será esta a forma correcta de o fazer?

Obrigado, de facto a introdução de um parâmetro de modelo fictício, no caso do exemplo, contorna o problema.
No entanto, quanto ao projecto global, as coisas são um pouco mais complicadas: aclasse interna foi utilizada como alternativa à funcionalidade de nome datilografia em falta, a fim de simplificar tanto o processo de desenvolvimento como a aplicação da classe final do recipiente.
Pode valer a pena esperar por uma correcção por parte dos criadores.
Como último recurso, todas as dependências terão de ser arrastadas para fora, na esperança de não haver mais compilação bem sucedida com comportamento indefinido em tempo de execução.

 

Para resumir a funcionalidade interna da classe,
podemos dizer claramente que lhe falta a funcionalidade de declaração da tipografia, pelo menos a sua forma primitiva, para a utilizar correctamente...
Portanto, em vez de um código C++ bastante compacto e claro:

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


Temos de construir uma vedação com #define e herança através de classe 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
};


E há aqui muito mais problemas do que possa parecer à primeira vista.
Ocorrem problemas quando se usa #define como declaração datilografada:

- não há maneira de passar o tipo de dados utilizados fora da classe (não há maneira de passar tipos de dados simples);
- é necessário controlar constantemente o âmbito do #define com o par #undef correspondente

Problemas na utilização da classe interna como declaração de dactilografia:
- é possível passar classe/tipo de dados estruturais utilizados fora da classe (tipos de dados simples não podem ser passados);
- a herança perde todos os construtores, eles têm de ser reescritos manualmente usando assinaturas da classe base;
- se a classe em que a declaração typedef é usada tem uma classe base, então através de namespaces sobrepostos não há maneira de usar o mesmo nome da declaração typedef;
- classes herdadas de classes, estruturas de estruturas, isto tem de ser constantemente controlado;
 
Devido à introdução de operadores de atribuições por defeito, surgiu a necessidade de proibir a execução de atribuições aleatórias para a classe base.
Para este efeito, os programadores acrescentaram "operator= delete".
No entanto, não parece lógico quebrar a ligação apagar/defazer, porque tudo precisa de ser escrito manualmente novamente.
Talvez eu esteja a fazer algo de errado?

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ão: