www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - foreach doesn't work when accessing elements as supertypes

reply xs0 <xs0 xs0.com> writes:
import std.stdio;

class Foo
{
}

class Bar : Foo
{
}

void fails()
{
	Bar[] bars=new Bar[100];
	foreach(Foo f; bars)
		writefln("Should work as well");
}

void succeeds()
{
	Bar[] bars=new Bar[100];
	Foo[] foos=bars;
	foreach(Foo f; foos)
		writefln("Works");
}

-----

 dmd test.d
test.d(14): foreach: Bar [] is not an array of test.Foo ----- This seems inconsistent to me. I can see why using foreach(inout Foo f; bars) {} would fail - writing a Foo into Bar[] is a bad idea, but the form above should work, or, alternatively, foos=bars should also fail (I prefer that it works, though, if it matters :). As it is now, it just doesn't make much sense, at least to me.. DMD 0.129 on WinXP xs0
Aug 10 2005
next sibling parent reply BCS <BCS_member pathlink.com> writes:
I agree, your code should be legal and work just fine.
However if you need something now, this quick workaround compiles:


import std.stdio;

class Foo
{
}

class Bar : Foo
{
}

void fails()
{
Bar[] bars=new Bar[100];

// cast bars to Foo ===========

foreach(Foo f; cast(Foo[])bars)
writefln("Should work as well");
}

void succeeds()
{
Bar[] bars=new Bar[100];
Foo[] foos=bars;
foreach(Foo f; foos)
writefln("Works");
}


In article <dddlpj$q05$1 digitaldaemon.com>, xs0 says...
This seems inconsistent to me. I can see why using

foreach(inout Foo f; bars) {}

would fail - writing a Foo into Bar[] is a bad idea, but the form above 
should work, or, alternatively, foos=bars should also fail (I prefer 
that it works, though, if it matters :). As it is now, it just doesn't 
make much sense, at least to me..

DMD 0.129 on WinXP


xs0
Aug 10 2005
parent xs0 <xs0 xs0.com> writes:
BCS wrote:
 I agree, your code should be legal and work just fine.
 However if you need something now, this quick workaround compiles:
Well, an even easier workaround is foreach(Bar f; bars) ... :) The things was that I changed some array to something more specific, and all the places where it was being read needed to be updated, which I think was quite needless... even more so, because you can implicitly cast the array anyway, just not in foreach.. xs0
 void fails()
 {
 Bar[] bars=new Bar[100];
 
 // cast bars to Foo ===========
 
 foreach(Foo f; cast(Foo[])bars)
     writefln("Should work as well");
 }
Aug 10 2005
prev sibling parent =?ISO-8859-1?Q?Thomas_K=FChne?= <thomas-dloop kuehne.THISISSPAM.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

xs0 schrieb:

 import std.stdio;
 
 class Foo
 {
 }
 
 class Bar : Foo
 {
 }
 
 void fails()
 {
     Bar[] bars=new Bar[100];
     foreach(Foo f; bars)
         writefln("Should work as well");
 }
 
 void succeeds()
 {
     Bar[] bars=new Bar[100];
     Foo[] foos=bars;
     foreach(Foo f; foos)
         writefln("Works");
 }
 
 -----
 
 dmd test.d
test.d(14): foreach: Bar [] is not an array of test.Foo ----- This seems inconsistent to me. I can see why using foreach(inout Foo f; bars) {} would fail - writing a Foo into Bar[] is a bad idea, but the form above should work, or, alternatively, foos=bars should also fail (I prefer that it works, though, if it matters :). As it is now, it just doesn't make much sense, at least to me.. DMD 0.129 on WinXP
Added to DStress as http://dstress.kuehne.cn/run/c/cast_29_A.d http://dstress.kuehne.cn/run/c/cast_29_B.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFC/mFE3w+/yD4P9tIRAj93AJ9bNmTXltgC6cujloPkioVALeyFCQCgk+Qg mYfNSz99eVAAUWV6A+7BMcQ= =M9wA -----END PGP SIGNATURE-----
Aug 13 2005