September 02, 2003
"Walter" <walter@digitalmars.com> a écrit dans le message news: bj0e06$2nf0$1@digitaldaemon.com...
> It's a bug. Since A[] is an array of references to A, B[] should be implicitly convertible to A[]. Thanks for finding it, this is an important one. -Walter

And what about it :

class A {}
class B : A {
  void crash() {};
}

void doSomethingWrong( A[] as ) {
    as ~= new A(); // doh !
}

void main() {

    B[] bs;

    doSomethingWrong(bs); // implicitly convertible you said

    bs[0].crash(); // oops...

}


-- Nicolas Repiquet


September 02, 2003
"DeadCow" <deadcow-remove-this@free.fr> wrote in message news:bj1vu2$1tke$1@digitaldaemon.com...
>
> "Walter" <walter@digitalmars.com> a écrit dans le message news: bj0e06$2nf0$1@digitaldaemon.com...
> > It's a bug. Since A[] is an array of references to A, B[] should be implicitly convertible to A[]. Thanks for finding it, this is an
important
> > one. -Walter
>
> And what about it :
>
> class A {}
> class B : A {
>   void crash() {};
> }
>
> void doSomethingWrong( A[] as ) {
>     as ~= new A(); // doh !
> }
>
> void main() {
>
>     B[] bs;
>
>     doSomethingWrong(bs); // implicitly convertible you said
>
>     bs[0].crash(); // oops...
>
> }

In this case, 'as' is an in variable, and resizing it won't affect bs. If it was rewritten so that 'as' is inout, then it will crash as you showed. I don't know what to do about this case - perhaps disallow such implicit conversions for an inout or out parameter?


September 02, 2003
I just realized there's another problem:

void doSomethingWrong(A[] as)
{
    as[0] = new A();
}

Now, main() will think that as[0] is a B, and crash away. This seems to be a rather large hole in typesafety. The same problem exists in C++, so maybe nobody cares anyway <g>.


September 02, 2003
"Walter" <walter@digitalmars.com> wrote in message news:bj2qee$1od$1@digitaldaemon.com...
> I just realized there's another problem:
>
> void doSomethingWrong(A[] as)
> {
>     as[0] = new A();
> }
>
> Now, main() will think that as[0] is a B, and crash away. This seems to be
a
> rather large hole in typesafety. The same problem exists in C++, so maybe nobody cares anyway <g>.

Interesting test case. Java throws a 'java.lang.ArrayStoreException' here, at the point where you try to store the A in the array that is really B

C++ is different, since arrays use store by value unless you make it an array of pointers. If I do, e.g.

#include <iostream>
using namespace std;

class A {
public:
 virtual void print() {
  cout << 'A' << endl;
 }
};

class B : public A {
public:
 virtual void print() {
  cout << 'B'  << endl;
 }

 virtual void B_func() {
  cout << 'C'  << endl;
 }
};

static void test( A* as[] )
{
 as[0]->print();
 as[0] = new A();
}


int main( int argc, char* argv[] )
{
 B** bs = new (B*)[1];
 bs[0] = new B();
 test( (A**) bs );        // needs explicit cast
 bs[0]->B_func();      // crashes, probably because the vtable of A's class
does not contain a pointer to B_func
}

So the need for an explicit cast should tell you that you're trying to do
something illegal: B** is not implicitly translated to A**
Although a rare case, I prefer the Java solution. The Java docs mention:
Object x[] = new String[3];
x[0] = new Integer(0);

as a typical case where such an exception would be thrown, and a more common one for that. Applicable to D too, Walter?



September 09, 2003
> I just realized there's another problem:
>
> void doSomethingWrong(A[] as)
> {
>     as[0] = new A();
> }
>
> Now, main() will think that as[0] is a B, and crash away. This seems to be
a
> rather large hole in typesafety. The same problem exists in C++, so maybe nobody cares anyway <g>.

Large indeed! We need to think of some nice way to prevent this in general, but to allow the programmer to do it if s/he *really* wants to (kind of like poking COM vtable entries)


September 09, 2003
In article <bjldla$2j4j$2@digitaldaemon.com>, Matthew Wilson says...
>
>> I just realized there's another problem:
>>
>> void doSomethingWrong(A[] as)
>> {
>>     as[0] = new A();
>> }
>>
>> Now, main() will think that as[0] is a B, and crash away. This seems to be
>a
>> rather large hole in typesafety. The same problem exists in C++, so maybe nobody cares anyway <g>.
>
>Large indeed! We need to think of some nice way to prevent this in general, but to allow the programmer to do it if s/he *really* wants to (kind of like poking COM vtable entries)

Store the class info as part of the array?

assert(as.classinfo = A.classinfo);






September 10, 2003
"Walter" <walter@digitalmars.com> a écrit dans le message news: bj2qee$1od$1@digitaldaemon.com...

> Now, main() will think that as[0] is a B, and crash away. This seems to be
a
> rather large hole in typesafety. The same problem exists in C++, so maybe nobody cares anyway <g>.

What about templates ?

class A {}
class B {}

template TFoo(T) {
    T[] ts;
    void add(T t) { ts ~= t; }
}

void doSomethingWrong( TFoo(Object) t ) {
    t.add(new B());
}

instance TFoo(A) a;

doSomethingWrong( a ); // implicit conversion


-- Nicolas Repiquet


1 2
Next ›   Last »