September 02, 2003 Re: Bug or feature? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "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 Re: Bug or feature? | ||||
---|---|---|---|---|
| ||||
Posted in reply to DeadCow | "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 Re: Bug or feature? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 Re: Bug or feature? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "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 Re: Bug or feature? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | > 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 Re: Bug or feature? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Matthew Wilson | 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 Re: Bug or feature? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "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 |
Copyright © 1999-2021 by the D Language Foundation