Errors, bugs, questions - page 2639

 
Aleksey Vyazmikin:

Is the portable mode key required by any chance?

Do all terminals start manually?

By hand, yes, they all do. In the end, that's how I started them manually.

The portable mode key doesn't change anything in this regard.

The thing is, MT4 throws up an authorization window and the program start is not considered completed.

You have to use "start" in the batch file.

All in all, it turns out I've got this one figured out.

Thank you for your participation!

 
Petros Shatakhtsyan:

You still don't understand what this is about, you probably don't read my posts carefully. My appeal is to the developers, not you. I don't need your cheap advice.

Calm down and do not worry so much.

Once again I am convinced that people with low brain development usually have little understanding of civility.

You can not even understand what you are told by more knowledgeable people, and you are as rude as a kindergarten child who has not even learned to write correctly.

 
Unfortunately, or maybe fortunately, I don't do any direct development,
However, it's the work on the projects that allows you to assess the language's capabilities and discover its defects and bugs...

Previously, when working on MQL projects, the information about defects (bugs) was provided in the order of their detection.
Now we have decided to try a new approach - work up to a blocking defect and then provide information about all detected defects.
 
#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;
}
Very nasty MT5(build 2316) bug, blocking further development.
You create a complex wrapped object with internal type "C" several times, but it turns out to be quite a different data type, maybe "B", "int", whatever you want...

I spent a lot of time and effort to find and understand that the problem is not in the code but in the MQL compiler. (C++ online:https://onlinegdb.com/H1R1fR5ML)
Presumably, the problem is in the work of the template class "main_wrapper" cache during code generation at compilation time when the internal class "internal_wrapper" from the template class "A" is passed as a parameter for different data types (int, B*, B, C).
What first data type is created by the template class "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>, such data type will be further used in all objects of the template in the future.


Another bug with the generation of the template class code will be provided below.
 
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;
}

Another MT5(build 2316) bug with template class code generation when using internal class.
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;
}

AnotherMT5(build 2316) defect related to theinternal class is the lack of ability to explicitly reference the global namespace.
C++ online:https://onlinegdb.com/H14NF05G8

 
Sergey Dzyublik:
A very nasty bug that blocks further development.
You create a complex wrapped object with internal type "C" several times, but it turns out to be quite a different data type, maybe "B", "int", whatever you want...

It took me a lot of time and effort to find and understand that the problem is not in the code but in the MQL compiler. (C++ online:https://onlinegdb.com/H1R1fR5ML)
Presumably, the problem is in the work of the template class "main_wrapper" cache during code generation at compilation time when the internal class "internal_wrapper" from the template class "A" is passed as a parameter for different data types (int, B*, B, C).
What first data type is created by the template class "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>, such data type will be further used in all objects of the template in the future.


Another bug with the generation of the template class code will be provided below.
#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
}
Is it correct?
 
Vladimir Simakov:
Is this the right way to do it?

Thank you, indeed introducing a dummy template parameter, in the case of the example, bypasses the problem.
However, as for the global project, it's a bit more complicated:the internal class was applied as an alternative to the missing typedef typename functionality in order to simplify both the development process and the application of the final container class.
It may be worth waiting for a fix from the developers.
As a last resort, all dependencies will have to be dragged outward, hoping for no further successful compilation with undefined behavior at runtime.

 

To summarize the internal class functionality,
we can clearly say that it lacks typedef declaration functionality, at least its primitive form, to use it properly...
So, instead of quite compact and comprehensible 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;
..............................


We have to build a fence with #define and inheritance through internal class:

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


And there are much more problems here than it may seem at first sight.
Problems occur when using #define as a typedef declaration:

- there is no way to pass the type of data used outside the class (there is no way to pass simple data types at all);
- it is necessary to constantly control the scope of #define with the corresponding #undef pair

Problems when using internal class as typedef declaration:
- it is possible to pass class/struct data type used outside the class (simple data types cannot be passed at all);
- inheritance loses all constructors, they have to be rewritten manually using signatures from the base class;
- if the class in which typedef declaration is used has a base class, then through overlapping namespaces there is no way to use the same name as typedef declaration;
- classes inherit from classes, structures from structures, this must be constantly controlled;
 
Due to the introduction of default assignment operators, the need arose to prohibit random assignment execution for the base class.
For this purpose, the developers added "operator= delete".
However, it doesn't seem logical to break the delete/default link, because everything needs to be written manually again.
Maybe I'm doing something wrong?

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