Bug 2412 – Hole in type system: array conversion to supertypes
Status
RESOLVED
Resolution
DUPLICATE
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2008-10-10T04:03:00Z
Last change time
2014-03-01T00:36:00Z
Keywords
accepts-invalid, spec
Assigned to
bugzilla
Creator
fraserofthenight
Comments
Comment #0 by fraserofthenight — 2008-10-10T04:03:04Z
Automatic conversion of an array of a subtype to an array of its supertype creates a hole in the type system (that is, you can get an invalid type without doing any casting). Consider the following legal D code:
module bug;
class A { }
class X : A { void hello() { } }
class Y : A { }
void main()
{
X[] xArray = new X[1];
A[] aArray = xArray;
aArray[0] = new Y();
X x = xArray[0]; // Automatic conversion of Y -> X without cast
x.hello(); // Likely segfault
}
The solution is to require an explicit cast from X[] to A[] (that is, any subtype array to its supertype).
Comment #1 by 2korden — 2008-10-10T05:18:04Z
It was previously discussed in newsgroups and rejected as invalid, IIRC. I.e. bug is on your side.
However, I totally agree that explicit cast is needed in this situation, as it violates SafeD otherwise.
Comment #2 by fraserofthenight — 2008-10-10T06:15:34Z
IIRC, in the most recent discussion, Walter/Andrei never commented. This is a dangerous situation because it could easily crop up in a large codebase and be _very_ hard to track down. It's also dangerous because the user would never know they're doing something wrong (i.e. there's no indication of danger and no uses of "unsafe" code like direct pointer use).
Comment #3 by schveiguy — 2008-10-10T08:27:53Z
I'd agree with this. It is inconsistent with how a pointer to a class is treated, which is essentially what an array of classes references is.
i.e.:
X x = new x;
A* a = &x; // fails to compile, requires cast.
Similarly, if I look at an array, it is a struct:
struct ArrayOfX
{
X *ptr;
uint length;
}
Casting this to:
struct ArrayOfA
{
A *ptr;
uint length;
}
Seems like you would theoretically have to go through the same cast as the code I wrote above, casting an X* to an A*.
The only drawback of this is you cannot return covariant arrays, or allow a subtype array to be used as the base type for a function call. I would guess this is a rare requirement.
One thing that should probably be allowed though in D2 is implicitly casting to a const(A)[]. This would prevent such mistakes as you have outlined. You can still explicitly cast if needed.
Comment #4 by dfj1esp02 — 2008-10-10T09:04:53Z
*** This bug has been marked as a duplicate of 2095 ***