Errors, bugs, questions - page 2357

 
Ilya Malev:

Thanks for the detailed answer, however, I don't understand the logic a bit.

1) Why does the compiler perceive the B* b1=a construct as a call to copy operator A::A(const A&), (instead of calling B::B(const A&), because it is class B to the left of operator=)

2) Why didn't the compiler generate the warning "copy constructor missing"?

3) why a "simple" method call is allowed for non-existing objects (while an attempt to call A::f() directly generates a compilation error "not a static method call")

1) I wrote that this is an obvious error that we'll fix anyway

2) the copy constructor is generated by the compiler, if it is not declared by the user

3) the question is not quite clear.
From the context of the discussion:
One could argue for a long time about whether or not to "dereference" a pointer if there is no access to it?
The dereferencing operation (getting the actual pointer from the handle) is "internal" (not custom) and expensive (compared to not having it) code.
Why perform dereferencing if there will be no pointer access ?
As long as it stays as it is, the dereferencing operation is removed by the optimizer if there is no pointer access.

 
Ilya Malev:

4) And why does the compiler allow a "simple" virtual method call at all? I don't think virtuality should depend on the presence or absence of data in the object

You're confusing the two.

The call devirtualization is a separate optimization method that has nothing to do with presence or absence of fields in an object.

 
Ilyas:

2) the copy constructor is generated by the compiler, unless declared by the user

There is a B object on the left, why is the A::A(A&) constructor called (or generated) for it? This contradicts the principles of OOP
 
Alexey Navoykov:
There's object B on the left, why is constructor A::A() called for it ?

Because in µl this is how the operators =, ==, !=, !&, &| and || always behave when there is a pointer on the left and an "object" on the right. And at the same time these operators cannot be overloaded on pointers.

So please, when you will fix this bug, make the above operators overloadable for dynamic objects.

 
Metatrader 4 has stopped working, it works for a second or so when I start up, then a one click trading window appears in the top left corner (Buy/Sell) and then the app closes.
Any suggestions on how to fix it?
Thanks in advance for your help.
 
Ilya Malev:

Because this is how the operators =, ==, !=, !&, && and || always behave in µl when the pointer is on the left and the "object" type is on the right.

What's the pointer got to do with it? I've already told you here. It works the same way here without pointer.
 
Alexey Navoykov:
There is object B on the left, why is the A::A(A&) constructor called (or generated) for it? This contradicts the principles of OOP

I completely agree with you and have already written that this is an error which will be corrected.

In this case, the compiler has picked up a suitable overload on inheritance, which should not have been done on the object's construction.

 
Ilyas:

One can argue for a long time about whether or not to "dereference" a pointer if there's no access to it.

The dereferencing operation (obtaining a real pointer from a handle) is "internal" (not custom) and expensive (compared to not having it) code.
Why perform dereferencing if there will be no pointer access ?

Because a list of virtual methods is part of an object's information, no less important than the data itself, and access to virtual methods is pointer access. For instance, if I write in my example

  A* aa=a;
  B* b1=a;   
  b1=aa;
  b1.f();

again I'll get B::f(), although this code explicitly refers to assignment of the A* object, which was "copied" from A and was referenced by A*. This is a deeper situation than calling the "wrong" copy constructor. But even if the object hadn't had any virtual methods, we still should have checked the validity of the pointer when accessing it.

 
Alexey Navoykov:
There's a B object on the left, why is the A::A(A&) constructor called (or generated) for it ? This contradicts the principles of OOP

Are you sure there's anything called there at all? I checked in x32:

class A {
public:
        A()           { Print(__FUNCSIG__); }
        A( const A& ) { Print(__FUNCSIG__); }
} a;
class B : public A {
public:
        B()           { Print(__FUNCSIG__); }
        B( const B& ) { Print(__FUNCSIG__); }
} *b = a;
void OnStart() {}

Result: A::A()
and nothing else!

 
A100:

Are you sure there's anything called there at all? I checked in x32:

Result: A::A()
and nothing else!

So, off to check generator/optimiser dumps to dot the I's

Reason: