错误、漏洞、问题 - 页 2639

 
Aleksey Vyazmikin:

是否需要便携式模式的钥匙?

所有终端都是手动启动的吗?

通过手工,是的,他们都是这样。最后,我就是这样手动启动它们。

便携式模式键在这方面没有任何改变。

问题是,MT4抛出一个授权窗口,程序启动不被认为已经完成。

你必须在批处理文件中使用 "开始"。

总而言之,事实证明我已经搞清楚了这个问题。

感谢你的参与!

 
Petros Shatakhtsyan:

你还是不明白这是怎么回事,你可能没有仔细阅读我的帖子。我的呼吁是针对开发商,而不是你。我不需要你的廉价建议。

平静下来,不要太担心。

我再次确信,大脑发育不良的人通常对文明的理解不深。

你甚至不能理解更有知识的人告诉你的东西,你就像一个甚至没有学会拼写的幼儿园孩子一样粗鲁。

 
不幸的是,也许是幸运的是,我不做任何直接的开发。
然而,正是在项目上的工作使你能够评估语言的能力 并发现其缺陷和错误......

以前,在MQL项目上工作时,有关缺陷(bug)的信息是按其检测顺序提供的。
现在,我们决定尝试一种新的方法--工作到阻断性缺陷,然后提供所有检测到的缺陷的信息。
 
#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;
}
非常讨厌的MT5(build 2316)错误,阻碍了进一步发展。
你创建了一个内部类型为 "C "的复杂包装对象,但结果却是一个相当不同的数据类型,可能是 "B"、"int",或者是你想要的任何类型...

我花了很多时间和精力才发现并了解到问题不在代码中,而是在MQL编译器中。(C++在线:https://onlinegdb.com/H1R1fR5ML)
据推测,问题出在模板类 "main_wrapper "缓存的工作中,在编译时,来自模板类 "A "的内部类 "internal_wrapper "被传递为不同数据类型(int, B*, B, C)的参数。
第一个数据类型是由模板类 "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>"创建的,这样的数据类型将来会在模板的所有对象中进一步使用。


下面将提供另一个关于模板类代码生成的错误。
 
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;
}

另一个MT5(build 2316)在使用内部类时模板类代码生成的错误。
C++在线: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;
}

另一个与内部类 相关的MT5(build 2316) 缺陷是缺乏明确引用全局命名空间的能力。
C++在线:https://onlinegdb.com/H14NF05G8

 
Sergey Dzyublik:
一个非常讨厌的错误,阻碍了进一步的发展。
你创建了一个内部类型为 "C "的复杂包装对象,但结果却是一个相当不同的数据类型,可能是 "B"、"int",或者是你想要的任何类型...

我花了很多时间和精力才发现并了解到问题不在代码中,而是在MQL编译器中。(C++在线:https://onlinegdb.com/H1R1fR5ML)
据推测,问题出在模板类 "main_wrapper "缓存的工作中,在编译时,来自模板类 "A "的内部类 "internal_wrapper "被传递为不同数据类型(int, B*, B, C)的参数。
第一个数据类型是由模板类 "main_wrapper<A<TEMPLATE_TYPE>::internal_wrapper>"创建的,这样的数据类型将来会在模板的所有对象中进一步使用。


下面将提供另一个关于模板类代码生成的错误。
#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
}
这是否正确?
 
Vladimir Simakov:
这是正确的做法吗?

谢谢你,的确,在这个例子中,引入一个假的模板参数,就能解决这个问题。
然而,至于全局项目,就有点复杂了:内部类 的应用是为了替代缺少的typedef typename功能,以简化开发过程和最终容器类的应用。
这可能值得等待开发者的修复。
作为最后的手段,所有的依赖关系将不得不向外拖动,希望在运行时没有进一步的成功编译与未定义行为。

 

总结一下内部类的功能。
我们可以明确地说,它缺乏typedef声明功能,至少是它的原始形式,以正确使用它......
因此,代替相当紧凑和清晰的C++代码。

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


我们必须用#define和通过内部类的继承来建立一个围栏。

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


而这里的问题比乍看起来要多得多。
当使用#define作为typedef声明时,会出现问题。

- 没有办法在类外传递使用的数据类型(根本就没有办法传递简单的数据类型)。
- 有必要用相应的#undef对不断控制#define的范围。

使用内部类作为typedef声明时的问题。
- 可以传递在类外使用的类/结构数据类型(简单的数据类型根本不能传递);
- 继承失去了所有的构造函数,它们必须使用基类的签名手动重写;
- 如果使用typedef声明的类有一个基类,那么通过重叠的名字空间,没有办法使用与typedef声明相同的名字;
- 类继承于类,结构继承于结构,这必须不断控制。
 
由于引入了默认的赋值运算符,出现了禁止基类的随机赋值执行的需要。
为此,开发人员增加了 "operator= delete"。
然而,打破删除/默认链接似乎不符合逻辑,因为一切都需要重新手动写入。
也许我做错了什么?

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