Errors, bugs, questions - page 1891

 
Renat Fatkhullin:

Sure.

Are you sure? Because dynamic_cast is most often used for bottom-up conversion, from parent to offspring.

Moreover, in MQL it perfectly casts from bottom to top, even when it shouldn't:

class A
{
public:
   virtual void f()
   {
      Print("1");
   }
};

class B: public A
{
public:
   virtual void f()
   {
      Print("2");
   }
};

void OnStart()
{
   A* ptr1 = new B();
   ptr1.f();
   A* ptr2 = new A();
   ptr2.f();
   
   B* casted = dynamic_cast<B*>(ptr1);
   casted.f();
   
   B* casted1 = dynamic_cast<B*>(ptr2);
   casted1.f(); // здесь должна быть ошибка потому что casted1 должен быть null
   delete ptr1;
   delete ptr2;
}

вывод:
2017.05.13 18:30:14.864    t ETHUSD,M5: 2
2017.05.13 18:30:14.865    t ETHUSD,M5: 1
2017.05.13 18:30:14.866    t ETHUSD,M5: 2
2017.05.13 18:30:14.867    t ETHUSD,M5: 2


Renat Fatkhullin:

Take a look at the discussed MQL5 code fragment.

Yes, it should not work and it's already explained above, but not because bottom-up cast is impossible.

 
Konstantin:
If we cast the pointer from top to bottom, i.e. to the parent, after which we pass the pointer to somewhere else in the scope, the fields of the descendant will be available there?

Yes, here is an example demonstrating your question:

class CLASS1
  {
public:
   int               i;
  };
class CLASS2 : public CLASS1
  {
  };
void OnStart()
  {
   CLASS1 _object;
   CLASS2 *_ptr=dynamic_cast<CLASS2 *>(&_object);

   if(!_ptr)
      Print("CLASS1 -> CLASS2 failed, null");

   CLASS2 *my=new CLASS2;
   CLASS1 *my_ptr=my;
   CLASS2 *my_ptr2=dynamic_cast<CLASS2 *>(my_ptr);

   if(my_ptr2)
     {
      Print("CLASS2 -> CLASS1 -> CLASS2 ok");
      my_ptr2.i=1;
     }
   Print("Value: ",my.i);
  }
and output:
2017.05.13 18:34:50.341 cast (EURUSD,H1)        CLASS1 -> CLASS2 failed, null
2017.05.13 18:35:18.933 cast (EURUSD,H1)        CLASS2 -> CLASS1 -> CLASS2 ok
2017.05.13 18:35:20.110 cast (EURUSD,H1)        Value: 1

First, we check the unresolved cast from the bottom up and get NULL. This is correct.

Then we create a CLASS2 object, assign a reference to it to its parent class (here it's important to understand that dynamically the environment knows that CLASS2 object's original type is stored in its meta-information). Then (just your question) dynamically cast (with conversion right checking based on source object's metainformation) from reference CLASS1 to CLASS2.

We check the result of casting and write it into variable i = 1. Finally we output the value of i, referencing the originally created object.

Everything works correctly and according to the specification (including the dynamic_cast spec of C++ itself).

 
Комбинатор:

Are you sure? Because dynamic_cast is most often used for bottom-up conversion, from parent to offspring.

Moreover, in MQL it perfectly casts from bottom to top, even when it shouldn't:

Exactly:

Don't forget to update to the latest builds. I'm currently testing on 1598, which was recently posted as a zipped version in this thread, I think.

 
Renat Fatkhullin:

Don't forget to update to the latest builds.

Yes, the old build.

Renat Fatkhullin:

That's right, you can't drive from the bottom up, only from the top down. This is for safety's sake.

You should wipe this one, it's misleading and directly contradicts dynamic_cast functioning
 
Комбинатор:

Yes, the old build.

You rub this one out, it's misleading and directly contradicts the functioning of dynamic_cast

As part of the CLASS1 -> CLASS2 head-to-head casting example raised, you got it right. That's the kind of casting most of the time people have in their heads.

Also, it's the "you can't cast from bottom to top, only from top to bottom" that's at the heart of the dynamic_cast safety check.

Those who know what they are doing understand the essence of dynamic_casting.

 
Renat Fatkhullin:

Don't forget to update to the latest builds. I'm currently testing on 1598, which was recently posted as a zip in this thread I think.

What exe file does the compiler and executor sit in?

Right now MT4b1080 is running MEb1599. Please explain what metaeditor.exe and terminal.exe do.

 
fxsaber:

What exe file does the compiler and executor sit in?

The MT4b1080 is now running MEb1599. Please explain what metaeditor.exe and terminal.exe do.

The compiler is the same for both platforms. It is in metaeditor.exe
 
Renat Fatkhullin:
The compiler for both platforms is the same. It is in metaeditor.exe
And the executor, which checks the same dynamic_cast, in terminal.exe ?
 
fxsaber:
And the executor, which checks the same dynamic_cast, in terminal.exe ?
Of course
 
Renat Fatkhullin:
Another question like this

Forum on trading, automated trading systems and trading strategy testing

Bugs, bugs, questions

fxsaber, 2017.05.11 13:26

Why EX5 such code
void OnStart() {}

Does it weigh 5kb?

Reason: