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

 

Forum on trading, automated trading systems and trading strategy testing

Bugs, bugs, questions

fxsaber, 2018.12.01 11:15

Super-brake design
string Str[];
const int handle = FileOpen(FileName, FILE_READ | FILE_ANSI | FILE_TXT);  

FileReadArray(handle, Str);

A 40Mb file of 1 million lines takes 18 seconds to read.


The same output result, but done differently

  uchar Bytes[];
  const int handle = FileOpen(FileName, FILE_READ | FILE_BIN);
  
  FileReadArray(handle, Bytes);

  string Str[];
  StringSplit(CharArrayToString(Bytes), '\n', Str);

Is already done in 0.5 seconds.


 
An artificial trick to compile
#define  MACROS(A, B) A / B + !(A / B) // (A >= B) ? A / B : 1

template <typename T1, typename T2>
union UNION
{
  T1 a;
//  T2 b[sizeof(T1) / sizeof(T2)];      // '[' - invalid index value
  T2 b[MACROS(sizeof(T1), sizeof(T2))]; // OK
};

template <typename T1, typename T2>
void f()
{
  if (sizeof(T1) >= sizeof(T2))
    UNION<T1, T2> Union;
  else
    UNION<T2, T1> Union;  
}

void OnStart()
{
  f<int, char>();
}
 

A simple counterpart to auto_ptr (considered obsolete). Note: not quite analogous, with
...


https://habr.com/post/140222/

Smart pointers для начинающих
Smart pointers для начинающих
  • habr.com
Эта небольшая статья в первую очередь предназначена для начинающих C++ программистов, которые либо слышали об умных указателях, но боялись их применять, либо они устали следить за new-delete. UPD: Статья писалась, когда C++11 еще не был так популярен. Итак, программисты С++ знают, что память нужно освобождать. Желательно всегда. И они знают...
 

pavlick_

A line at the beginning should be added to operator=:

if (p==other.p) return &this;
 

Although it's probably worth limiting yourself to something like this (you can't copy at all):

template <typename T_>
class unique_ptr{
   T_ *p;
public:
   unique_ptr(void *ptr=NULL): p(ptr)           {}
   ~unique_ptr()                                {reset();}
   unique_ptr *operator=(T_ *p_)                {reset(); p = p_; return &this;}
   // releases ownership of the managed object
   T_ *release()                                   {T_ *r = p; p = NULL; return r;}
   // destroys the managed object 
   void reset()                                    {if(p) delete p; p=NULL;}
   // returns a pointer to the managed object 
   T_ *get()                                       {return p;}
   unique_ptr(const unique_ptr<T_> &other);
   void operator=(const unique_ptr<T_> &other);
   void swap(unique_ptr<T_> &other){
      T_ *buf = p;
      p = other.p;
      other.p = buf;
   }
};
Why did I make copying for auto_ptr? Because of curvature of µl - to copy stack object to CArrayObj you have to create a bunch of objects by calling the constructor a bunch of times. But I don't think it's worth it. In this regard, I'll take down the first post.
 
pavlick_:

Why did I make copying for auto_ptr? Because of the curvature of µl - to copy a stack object to CArrayObj you have to create a bunch of objects by calling the constructor a bunch of times.

And why "the curvature of μl"?

 
Alexey Navoykov:

And why the "crookedness of the µl"?

The trivial task of adding a copy of a stack object to an array is to add a default constructor, which I didn't need in the first place:

class Q : public CObject {
public:
   Q() {}
   Q(int i) {}
};

void OnStart()
{
   CArrayObj ar;
   Q q(3);
   
   Q *new_el = new Q;
   new_el = q;
   ar.Add(new_el);
   Q new_el2(5);
   q = new_el2;
}

It's not fatal, yes, you can do init() at Q, which will smooth the problem out a bit, but still - it's disgusting. And when copying auto_ptr on hand, everything happens in two lines, but the game is not worth the effort. Perhaps too picky, perfectionism.

 
pavlick_:

The trivial task of adding a copy of a stack object to an array turns out to be this + I need to prescribe a default constructor, which I didn't need at all:

It's not fatal, yes, you can do init() at Q, which will smooth the problem out a bit, but it's still disgusting. And when copying auto_ptr on hand, everything happens in two lines, but the game is not worth the effort. Perhaps too picky, perfectionism.

But it's exactly the same in C++ too, so it's not really clear why the crooked mcl.

And in your case it's easier to specify copy constructor, and add elements with one line:

ar.Add(new Q(q));
 
pavlick_:

The trivial task of adding a copy of a stack object to an array turns out to be this + I need to write a default constructor, which I didn't need at all:

It's not fatal, yes, you can do init() at Q, which will smooth the problem out a bit, but it's still disgusting. And when you have copying auto_ptr, everything happens in two lines, but the game is not worth the effort. Perhaps too picky, perfectionism.

That's how it all happens anyway - it's just hidden behind your auto_ptr...

I don't see any special problems here.

As a hardened old timer, I really dislike C# approach where memory is deleted automatically. To my mind, it's the person who requested the deletion of objects, not some "rubbish collectors" who should be responsible for it.

 
Alexey Navoykov:

But it's exactly the same in C++, so it's not very clear why the mcl is crooked.

And in your case it's easier to specify a copy constructor, and add elements in one line:

How is it the same? There's a copy constructor there automatically and all manipulations will have a look:

class Q : public CObject {
public:
   Q(int i) {}
};

void OnStart()
{
   CArrayObj ar;
   Q q(3);
   
   ar.Add(new(q));
   q = Q(5);
}

And in your case it's easier to set copy constructor and add elements with one line

Of course, it's a toy class for example, in reality it's some data too, probably a lot, it's not an option to write a copying constructor at all. Wrapped the right places in wrappers and no need for a custom constructor.

So it all happens anyway - it's just hidden behind your auto_ptr...

I don't see any particular problem here.

As a hardened old timer, I don't like C# approach where memory is deleted automatically. To my mind, the person who requested the deletion of objects should be responsible for it, not some rubbish collector.

In µl, you can do without smart pointers. Rubbish collector != smart pointers, you can't do without them at least because of exceptions. I don't like rubbish collector myself.

Reason: