Errors, bugs, questions - page 1183

 
Zeleniy:

When testing the Expert Advisor, it generates an error

invalid takeprofit for OrderSend function

OrderSend error 4107

How can I fix it without going into the code?

in the settings try to increase or decrease takeprofit
 
mql5:
The ZeroMemory function cannot be used for this object

I see. But why does the compiler show this error not in a place whereZeroMemory is used but in a place where the class is defined? It's confusing. I've already racked my brains trying to figure out what the error is and where it is located. Please make sure that the error is shown in a right place. For example, when copying an object containing items not allowed to be copied, the error occurs exactly in the line with copying and not somewhere inside the class.

 
meat:

Coming to the practical side of all this, I have already encountered a problem. The code was using static objects. Then I decided to replace some of them with dynamic ones. As the result, comparison and assignment operations started working quite differently. And this problem was difficult to detect because the program continues to compile and work normally but not in the way it should.

I did not immediately understand the problem

class B {};

class A {
public:
        bool operator !=( A* a ) { Print( __FUNCTION__ ); return ( true  );  }
        bool operator !=( B* b ) { Print( __FUNCTION__ ); return ( false );  }
        bool operator >>( A* a ) { Print( __FUNCTION__ ); return ( true  );  }
        bool operator +( A* a )  { Print( __FUNCTION__ ); return ( false  ); }
        bool operator !()        { Print( __FUNCTION__ ); return ( true   ); }
};

void OnStart()
{
        A *a = new A;
        B *b = new B;
        if ( a != a ) Print( "1" );
        if ( a != b ) Print( "2" );
        if ( a >> a ) Print( "3" );
        if ( !a )     Print( "4" );
        delete( a );
        delete( b );
}
From this you can see that (a != a) leads to comparison of pointers while (a >> a) leads to call operator >>( A* )

There is a contradiction.

You cannot change the behaviour of (a >> a) like other overloaded operators (except for == and !=) because it will make the following construct impossible, since you cannot return (A) but can only return (A*).

class A {
public:
        A *operator >>( string str ) { return ( GetPointer( this ) ); }
};

void OnStart()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили"; //множественное применение оператора <<
}

It will also be impossible to fully use overloaded operators because there is no pointer-to-object conversion operation (*a)

The only thing left to do is to change the (== and !=) behavior

To compare pointers (== and !=) with each other and with number zero (because other pointer operations are meaningless), one should introduce a special function like (GetPointer) or explicitly specify a type conversion to the compiler

void OnStart()
{
        A *a = new A;
        B *b = new B;
        if ( ulong(a) != ulong(b) ) Print( "2" ); //хочу сравнить указатели
         if (       a  !=       b  ) Print( "2" ); //хочу вызвать operator !=( B* )

}

Thus, the possibility of full-fledged use of overloaded operators will be preserved and the above mentioned contradiction will be eliminated

The only reasonable exception to the general rule should remain operator=() because


class A {
public:
        A *operator =( A* a ) { return ( GetPointer( this ) ); }
};
void OnStart()
{
        A *a = new A;
        a = a; //не должно трактоваться компилятором как вызов operator=( A* ),
                // а должно остаться как присваивание указателю значения
}
 
And of course the proposal to use (*a) at least for operators - go back to C++ notation
class A {
public:
        bool operator !=( A* a ) { Print( __FUNCTION__ ); return ( true  );  }
};

void OnStart()
{
        A *a = new A;
        if (  a !=  a ) Print( 1 ); //сравнение указателей
        if ( *a != *a ) Print( 2 ); //вызов operator !=( A* )
}

would eliminate all contradictions at once.

Correction: actually, contradictions are eliminated only partially, because such notation (*a) does not solve the problem of multiple use of operators (which now successfully works with all operators, except == and !=) - so the best way to compare pointers to each other on equality/inequality is still using special function - or explicit conversion to ulong type

 
A100, thanks for the messages, we'll sort it out.
 
Compilation error
class A {
public:
      A( int a1 ) : a3( a1 ) { }
  static int a2;
        int a3;
};
int A::a2 = 1;

void OnStart()
{
        int b = A::a2;  //нормально
        A t1( b );     //нормально
        A t2( A::a2 ); //ошибка компиляции
        A* t3 = new A( A::a2 ); //нормально
}
if a static member argument of a constructor (except new)
 
Compiler does not allow comments inside #define after transferring
#define  f( x )                   \
        ( x != 0 &&  /*comment*/\ 
          x != 1 )

this is fine, and this

#define  f( x )       \
        ( x != 0 &&  \ /*comment*/
          x != 1 )
compilation error
 

Continuing the theme about pointers, it would be nice to add to MQL standard operator of taking a pointer'&', it would be much more convenient and compact than cumbersome GetPointer.Thus, having * and & operators in our arsenal, we will be able to explicitly define the necessary operations:

if (&a==&b) Print("Указатели равны");
if (*a==*b) Print("Объекты равны");


And there's more about this ampersand. MQL lacks reference to variables, especially taking into account the limited use of pointers (only to class objects). The function often requires access to a deeply nested structure element or a multidimensional array. I have to write the full path to it each time, which makes the code very cumbersome.You can simplify things by creating a reference and sometimes you just have to "change" a variable's name locally for convenience. However, what am I explaining here? Everybody already knows how convenient it is to use references but now you have to use #define instead, which is certainly not good.

And we also need the capability of passing the result of a function by reference, i.e. double& Func() { }

 

Facebook has recently seen the emergence of backlinking of posts from blogs:

1

 
meat:

Keeping on the theme of pointers, it would be good to add to MQL a standard operator of taking a pointer'&', it would be much more convenient and compact than cumbersome GetPointer.Thus, having * and & operators in our arsenal, we'll be able to explicitly define the necessary operations:

Adopting only (*a) to refer to member functions does not give any clear advantages, but instead makes it impossible to use the operators in a simple and clear way.

class A {
public:
        A *operator >>( string str ) { Print( __FUNCTION__); return ( GetPointer( this ) ); }
};

void OnStart()
{
        A *a = new A;
        a << "1234" << "мы" << "всю ночь" << "тусили"; //простая и понятная запись

Try to rewrite it taking your suggestion into account

void OnStart()
{
        A *a = new A;
        *(*(*(*a << "1234") << "мы") << "всю ночь") << "тусили"; //запутанная запись
}

You cannot use the object itself instead of the pointer because operator <<(...) can return only a pointer to the object.

What operations with pointers are meaningless? - Only comparison to each other and to a number - consequently, they should be neglected and put into a special function (for example, bool ComparePointer( a,b)) for the sake of preserving the possibility of multiple use of operators without which the operator overload itself loses its meaning.

Reason: