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

 

MT5 build 1940

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
class A
{
public:
    int iValue;
};
//......................
A m_A[2];

void OnStart()
{
A a;

    m_A[0] =a; 
    m_A[1] = new A();
}
//+------------------------------------------------------------------+

It compiles in both cases:

A m_A[2]; // и так

A* m_A[2]; // и так

In the first case, the output is an object that is not deleted (created new) and a memory leak

1 undeleted objects left
1 object of type A left
24 bytes of leaked memory

Ok, freeing manually ... and then the compiler (suddenly) notices that the array contains non-pointers:"object pointer expected"

delete m_A[1]; // Если 'm_A' массив объектов -> object pointer expected

Ok, I declare it as a pointer array.

A* m_A[2];

It compiles! This was news to me. So, do MQL have pointers or not? Because with built-in types like char, int, etc. there will be

'*' - pointer cannot be used

But this time it will be at runtime.

m_A[0] =a; // получаем: "invalid pointer access"

Which is logical in principle).

There are some questions regarding the results:

1. What for are these subpointers in MQL, if they don't serve their main function, as the pointers do in C/C++?

2. Why should we play with delete, if MT knows to the exact byte how much memory has leaked and can release it automatically?

 

When deleting, you have to check the pointer type. One object is created with new - it must be deleted (second in the example) and the other one is automatic (first in the example), it will be deleted automatically.

 
Dmitry Fedoseev:

When deleting, you have to check the pointer type. One object is created with new - it must be deleted (second in the example), and the other is automatic (first in the example), it will be automatically deleted.

I.e. in the first casem_A[0] will not containa copy of stackobject'a' but pointer of somePOINTER_AUTOMATIC type to that local object which will becomePOINTER_INVALID typeafter exiting the function (if it were called from another function)?

 
Then, in general, the problem sounds like this: the compiler allows a pointer of typePOINTER_AUTOMATIC to be saved into a pointer of typePOINTER_DYNAMIC, and vice versa.
 
SemenTalonov:

I.e. in the first casem_A[0] will not be a copy of stackobject'a' but a pointer of somePOINTER_AUTOMATIC type to that local object which will becomePOINTER_INVALID typeafter exiting the function (if it were called from another function)?

Anything can become an INVALID, if it's not used correctly. The point is not thatPOINTER_INVALID, but that an object created automatically will also be deleted automatically.

In no case a copy of an object can be created here at all. A pointer is just a pointer - a variable with a number indicating where the object is, in this case object "a". So, you can refer to the object "a" with "a" or "m_A[0]", it is one object, not two different ones.

The principle is simple: you created the object, delete it yourself. If you didn't create it, leave it alone. It is as easy as that.

 
SemenTalonov:
In general, the problem sounds like this: the compiler allows you to save a pointer of thePOINTER_DYNAMIC type into a pointer of thePOINTER_AUTOMATIC typeand vice versa.

Vice versa. A pointer ofPOINTER_DYNAMIC typecan be assigned to a pointer ofPOINTER_AUTOMATICtype.But this is correct and good - it opens a lot of possibilities.

 

I don't understand what's wrong?

We take an array of objects and equate its first element to the object created on the stack. At the same time, without declaring the copy operator ! This is already an error.

Well, taking into account that the object is very simple, the copy constructor is generated there by default. And the array contains a copy of the created object.

No problem with the questions.

1. Pointers fulfill their role, and I personally only miss pointers to an array.

MQL shouldn't delete what it hasn't marked. Dmitriy was right when he said, "Create an object, delete it". I don't like the "rubbish collector" practice in C# where objects are deleted not when I want but when the assembler wants to.

 
Georgiy Merts:

I don't understand what's wrong?

We take an array of objects and equate its first element to the object created on the stack. At the same time, without declaring the copy operator ! This is already an error.

Well, taking into account that the object is very simple, the copy constructor is generated there by default. And the array contains a copy of the created object.

That's what I was expecting a copy of... The default copy constructor is not an error.

ButDmitry states that a new object will be allocated in memory and a pointer of thePOINTER_AUTOMATIC type will be returnedand there will be no copy.

Everyone understands MQL quirks in his own way)

 
SemenTalonov:

That's what I was expecting the copy... The default copy constructor is not an error.

ButDmitry says a new object will be allocated in memory and a pointer ofPOINTER_AUTOMATIC type will be returned.

Everyone understands MQL quirks in his own way)

What do you mean "no error"? You are using an operator that is not defined.

Well, you've got a practically empty object there, but what if there were other subobjects in this object, which would require initialization, and this object itself would require a resource request ?

Sounds to me like you can't use something that's not declared.

"Quirks" I didn't see, I think Dimitri is wrong about "no copy of the object" - and the reason, again, is that an undeclared statement is used.

 

Where does a copy of an object come from? A copy of a pointer, yes, but pointing to the same object.

 
Georgiy Merts:

What do you mean by "no error" ??? You're using an operator that's not defined.

My point is that an explicitly declared copy constructor would not change anything in this test.

How can you not see the obvious...

A pointer goes to an item of an object array and an object goes to an item of an array of pointers... is it really okay?

in the first case the array goes a pointer to an object in the second case the copy constructor should work, how can these operations be equivalent?