MQL5 The compiler does not distinguish between a class and a pointer to it - page 5

 
The = sign copies one object's memory area to another object's memory area. All objects remain where they were.
 
Vladimir Simakov:
There's no way to trigger it. It's pure memory leakage.

Make it so that it can be summoned.

 

By the way, gentlemen developers, we'd better fix this. After all, new does return a pointer, so add a check that at the other end = also a pointer, remove the implicit conversion (A) new A(); as I understand it - this is what happens.

 
Vladimir Simakov:

By the way, dear developers, we'd better fix this. After all new really returns a pointer, so add a check that the other end = also a pointer, remove the implicit conversion (A) new A(); as I understood it - this is what happens.

There's a call for this operator

Forum on trading, automated trading systems & strategy testing

MQL5 Compiler does not distinguish between a class and a pointer

fxsaber, 2019.01.10 06:36

Since when are these defined (question for developers)

void A::operator =( const A& );
void A::operator =( const A* );

And how do they work? The following compiled code looks delusional

    A* b = NULL;    
    m_A[1] = b;    


Roughly speaking, it looks like this

class A
{
public:
    int iValue;
    
    void operator =( const A* Ptr )
    {
      Print(__FUNCSIG__);
      
      this.iValue = Ptr.iValue;
    }
};
//......................
A m_A[2];

void OnStart()
{
A a;

    m_A[0] =a; 
    m_A[1] = new A();
}
 
fxsaber:

There goes the call to this operator


Roughly speaking, it looks like this

Yeah, I get it. It's not a bad rake. By the way, this operator overload = does not exist in C++, VS swears.
 

Before making a fuss, it would be good to know that in MQL all their life pointers have been implicitly cast to objects (dereferenced), it's convenient and everybody got used to it. Instead of hard-to-read a()->b()->c()->d() you can write in the usual OOP format: a().b().c().d(), and do less unnecessary transformations while passing to functions. And now because of someone's dissatisfaction you change everything?

 
Alexey Navoykov:

Before you make a fuss about it, it would be nice to know that in MQL all their life pointers have been casted to objects implicitly (dereferenced), it's convenient and everyone got used to it. Instead of hard-to-read a()->b()->c()->d() you can write in the usual OOP format: a().b().c().d(), and do less unnecessary transformations while passing to functions. And now because of someone's dissatisfaction you change everything?

It's not about casting. You didn't get into it.

 

If we are guided by the declared prototype of MQL - C++.

In C++, the new operator returns a pointer, respectively, if m_A is an array of objects:

m_A[1] = new A();

there would be a type error here.

This is the line the compiler would have skipped:

m_A[1] = *( new A() );

But it would cause a memory leak.


It would be nice if MQL had the same behavior.

 
Alexey Navoykov:

Before you start making a fuss about it, you should know that in MQL all their lives pointers have been implicitly cast to objects (dereferenced), it's convenient and everyone got used to it. Instead of hard-to-read a()->b()->c()->d() you can write in the usual OOP format: a().b().c().d(), and less unnecessary transformations in the process of passing to functions. And now because of someone's dissatisfaction you change everything?

And if you go into detail with some simple examples.

A a;

// 'a' ожидает объект
 
a = new A(); // а ему дают указатель, ведь можно же

// что в MQL равнозначно?
a = *(A*) new A();

As a result, we have

1. a' gets a copy of the created object, the pointer to the created new object is lost

2. What will happen to 'a' if new fails to create/memory allocate an object?

The second case (on the contrary)

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)
a = &b;

1. After exiting the function, the 'b' object must be destroyed as a local object.

what will 'a' refer to then?

2. or will the copy operator still work and 'b' will be copied by the 'a' pointer ? and if 'a' hasn't been defined before ?

 
SemenTalonov:

The second case (on the contrary)

A* a; // глобальный указатель - 'a' ожидает указатель на объект

// далее всё происходит внутри некой функции
A b; // создаем второй в стеке (ну типа в стеке, не суть)

a =b;
// т.е. тут объект "неявно кастится" к указателю?)


Here it's vice versa - a pointer a is implicitly casted to an object (dereferenced) and then operator= is applied to it. fxsaber also mentioned it yesterday.

Although logically it does not contradict the MQL rules (since calling operator= is equivalent to calling any other object method), it leads to ambiguous understanding of such code and hard-to-find errors. And this concerns not only operator= but == and != as well, at least. Perhaps such casting should be prohibited for other operators as well, because in C++ you may apply to operators: +-<>[].

The short verdict is this: when applying operators which are allowed for pointers in C++ to a pointer, disallow an implicit casting of this pointer to an object. Correspondingly, the above example would cause a compilation error.

Reason: