www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Implicit array conversions - something rotten

reply Mike Capp <mike.capp gmail.com> writes:
I was reading the "Implicit Conversions" section of arrays and did a
double-take; several of the conversions listed looked flat-out wrong. A bit of
experimentation muddied the waters further - several documented conversions
don't work, and several documented conversions that I was convinced had to be
typos do. 

Most importantly, D really will implicitly cast from a Derived[] to a Base[].
This is a huge hole in type-safety - it lets you put an object of ANY class into
an array of ANY class type without ever writing an explicit cast. I don't know
of any other statically-typed OO language that allows it.

#class Base {}
#class Derived : Base {}
#
#void main()
#{
#	Base b = new Base;
#	Derived d = new Derived;
#
#	Base* pb;
#	Derived* pd;
#	void* pv;
#
#	Base[3] sab;
#	Derived[3] sad;
#
#	Base[] dab;
#	Derived[] dad;
#	void[] dav;
#
#	// Check whether documented implicit conversions actually compile
#
#	// pb = pd;   // ERROR
#	pv = pd;
#	pd = sad;
#	dad = sad;
#	// sab = sad; // ERROR
#	// dab = sad; // ERROR
#	// pb = sad;  // ERROR
#	pv = sad;
#	dav = sad;
#	pd = dad;
#	dab = dad;
#	// pb = dad;  // ERROR
#	pv = dad;
#
#	// Determine whether dubious conversions involve copies
#
#	sad[1] = d; dad = sad; sad[1] = null;
#	if (dad[1] is null) printf("dad = sad : does not copy\n");
#
#	dad[1] = d; dab = dad; dad[1] = null;
#	if (dab[1] is null) printf("dab = dad : does not copy\n");
#
#	// Demonstrate gaping hole in type-safety
#
#	class Fruit {};
#	class Apple : Fruit {};
#	class Orange : Fruit {};
#
#	Apple[] apples;
#	apples.length = 3;
#	Fruit[] fruits = apples;
#	Orange orange = new Orange;
#	fruits[1] = orange;
#
#	if (apples[1] == orange) printf("Oops\n");
#}
Aug 07 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Mike Capp" <mike.capp gmail.com> wrote in message 
news:dd5v4m$vk2$1 digitaldaemon.com...
I was reading the "Implicit Conversions" section of arrays and did a
 double-take; several of the conversions listed looked flat-out wrong. A 
 bit of
 experimentation muddied the waters further - several documented 
 conversions
 don't work, and several documented conversions that I was convinced had to 
 be
 typos do.

 Most importantly, D really will implicitly cast from a Derived[] to a 
 Base[].
 This is a huge hole in type-safety - it lets you put an object of ANY 
 class into
 an array of ANY class type without ever writing an explicit cast.
I agree http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/3681
 I don't know
 of any other statically-typed OO language that allows it.
C++ allows it because C++ is C++ (by which I mean arrays are pointers). Java and C# allows the conversion but performs a run-time check when assigning into the array to make sure the the array type is compatible with the element being inserted.
 #class Base {}
 #class Derived : Base {}
 #
 #void main()
 #{
 # Base b = new Base;
 # Derived d = new Derived;
 #
 # Base* pb;
 # Derived* pd;
 # void* pv;
 #
 # Base[3] sab;
 # Derived[3] sad;
 #
 # Base[] dab;
 # Derived[] dad;
 # void[] dav;
 #
 # // Check whether documented implicit conversions actually compile
 #
 # // pb = pd;   // ERROR
 # pv = pd;
 # pd = sad;
 # dad = sad;
 # // sab = sad; // ERROR
 # // dab = sad; // ERROR
 # // pb = sad;  // ERROR
 # pv = sad;
 # dav = sad;
 # pd = dad;
 # dab = dad;
 # // pb = dad;  // ERROR
 # pv = dad;
 #
 # // Determine whether dubious conversions involve copies
 #
 # sad[1] = d; dad = sad; sad[1] = null;
 # if (dad[1] is null) printf("dad = sad : does not copy\n");
 #
 # dad[1] = d; dab = dad; dad[1] = null;
 # if (dab[1] is null) printf("dab = dad : does not copy\n");
 #
 # // Demonstrate gaping hole in type-safety
 #
 # class Fruit {};
 # class Apple : Fruit {};
 # class Orange : Fruit {};
 #
 # Apple[] apples;
 # apples.length = 3;
 # Fruit[] fruits = apples;
 # Orange orange = new Orange;
 # fruits[1] = orange;
 #
 # if (apples[1] == orange) printf("Oops\n");
 #}

 
Aug 07 2005
parent Mike Capp <mike.capp gmail.com> writes:
In article <dd625n$11rs$1 digitaldaemon.com>, Ben Hinkle says...
"Mike Capp" <mike.capp gmail.com> wrote in message 
news:dd5v4m$vk2$1 digitaldaemon.com...
 Most importantly, D really will implicitly cast from a Derived[] to a 
 Base[]. [...] I don't know
 of any other statically-typed OO language that allows it.
C++ allows it because C++ is C++ (by which I mean arrays are pointers).
But D uses reference semantics for all objects of class type, so Object[] in D corresponds to Object** in C++, not to Object*. And there's no implicit Derived** to Base** conversion in C++. cheers Mike
Aug 07 2005