Features of the mql5 language, subtleties and tricks - page 282

 
Alexey Viktorov #:

Then what's unusual, special about it?

Everything is very simple. I think it is desirable to take this phenomenon into account when writing optimal code. Someone does not think so.

I think it is right for me to write about it in this thread. Someone does not think so.

 
fxsaber #:

It is very simple. I think it is desirable to take this phenomenon into account when writing optimal code. Some people don't think so.

I think it is right for me to write about it in this thread. Someone does not think so.

I don't mind, but it's just desirable to see such explanations at once so that such questions don't arise. But now you read it and think: "What is this about?". And as for the optimal code, I think it is the worst thing to pick through history. Though it's for amateurs...

 
Alexey Viktorov #:

I don't mind, but it's just desirable to see such explanations at once so that such questions don't arise. Otherwise, you read it and think: "What's this about?". And as for the optimal code, I generally consider it the worst thing to dig into history. Though it's for amateurs...

Is there any way to learn history without picking at history? Give me a hint.

 
fxsaber #:
I noticed that the compiler does not swear at such a construction.

Of course, it is not a conversion of a pointer into an object, but in some situations such a construction is reasonable for speeding up.

What is the difference between

a = &a;

from

a = a;

for that particular code?

[edit]

Doesn't '&a' mean 'GetPointer(a)' ? And then the implicit operator= takes the reference.

  1. reference (automatic object initially) -->
  2. pointer (as a result of &) -->
  3. reference (pointer converted by compiler into a reference for passing to operator=(const A&))
I could be wrong, I haven't checked, but at first glance your code should work exactly as I described it
 
Artyom Trishkin #:

Is there any way to know history without picking at history? Give me a hint.

It's a secret...)

 
Vladislav Boyko #:

Doesn't '&a' mean 'GetPointer(a)' ? And then the implicit operator= takes the reference.

  1. reference (automatic object initially) -->
  2. pointer (as a result of &) -->
  3. reference (pointer converted by compiler into a reference for passing to operator=(const A&))
I may be wrong, I haven't checked, but at first glance your code should work exactly the way I described

It works exactly like that.

 
fxsaber #:

That's exactly how it works.

I can't understand the meaning of 'a = &a' for that particular example. Why not replace it with 'a = a' ?

[edit]

In the case of two pointers, I would explicitly call operator= just in case😅

class A {};

void OnStart()
  {
   A* a1;
   A* a2;
   a1.operator=(a2);
  }
Although, with two pointers this is probably the only way to call operator=
 
Vladislav Boyko #:

I can't understand the meaning of 'a = &a' for that particular example. Why not replace it with 'a = a' ?

Example.
#define  SIZE 200

class A
{
private:
  double Array[SIZE];
  
public:
  double operator []( const int Pos ) const
  {
    return(this.Array[Pos]);
  }
};

void OnStart()
{
  double Sum = 0;

  A a1, a2;
  A* a = new A;  

  A b = a; // Аналогия a = &a;
//  #define a b // Ускорение.
   
  const ulong StartTime = GetMicrosecondCount();
  
  for (int i = 0; i < 1 e7; i++)
    Sum += a[i % SIZE] + a1[i % SIZE] + a2[i % SIZE]; 
    
  Print((string)(GetMicrosecondCount() - StartTime) + " mcs.");

  #undef  a
    
  delete a;
}
 
Vladislav Boyko #:

In the case of two pointers, I would explicitly call operator= just in case😅

Although, with two pointers that's probably the only way to call operator=

Yes.

class A
{
public:  
  void operator =( const A* ) { Print(__FUNCSIG__); }
};

void OnStart()
{
  A* a = new A;
  
  a = a; 	  // Хорошо, что не принтует.
  a.operator=(a); // Принтует, как надо.
  
  delete a;
}
 
fxsaber #:
Example.

I get it. I'd probably prefer to wrap in a method. Although this particular dodgy test shows that your option of copying the object is a bit faster.

#define  SIZE 200

class A
{
private:
  double      Array[SIZE];
public:
              A() { for(int i = 0; i < SIZE; i++) Array[i] = 1.0 / (i + 1); }
  double      operator []( const int Pos ) const { return(this.Array[Pos]); }
  static void test1();
  static void test2(const A& a, const A& a1, const A& a2);
};

void OnStart()
  {
   A::test1();
   //---
   A a1, a2;
   A* a = new A;
   A::test2(a, a1, a2);
   delete a;
  }

void A::test2(const A &b,const A &a1,const A &a2)
  {
   double Sum = 0;
   const ulong StartTime = GetMicrosecondCount();
   for (int i = 0; i < 1 e7; i++)
      Sum += b[i % SIZE] + a1[i % SIZE] + a2[i % SIZE]; 
   PrintFormat(__FUNCTION__" %I64i mcs, sum %f", GetMicrosecondCount() - StartTime, Sum);
  }

void A::test1(void)
  {
   double Sum = 0;
   A a1, a2;
   A* a = new A;  
   A b = a;
   const ulong StartTime = GetMicrosecondCount();
   for (int i = 0; i < 1 e7; i++)
      Sum += b[i % SIZE] + a1[i % SIZE] + a2[i % SIZE]; 
   PrintFormat(__FUNCTION__" %I64i mcs, sum %f", GetMicrosecondCount() - StartTime, Sum);
   delete a;
  }