Jump to page: 1 2
Thread overview
Bug or feature?
Aug 31, 2003
Helmut Leitner
Aug 31, 2003
Jeroen van Bemmel
Aug 31, 2003
Vathix
Sep 01, 2003
Helmut Leitner
Sep 01, 2003
Jeroen van Bemmel
Sep 01, 2003
Walter
Sep 02, 2003
Jeroen van Bemmel
Sep 02, 2003
Helmut Leitner
Sep 02, 2003
Walter
Sep 02, 2003
DeadCow
Sep 02, 2003
Walter
Sep 02, 2003
Walter
Sep 02, 2003
Jeroen van Bemmel
Sep 09, 2003
Matthew Wilson
Sep 09, 2003
Patrick Down
Sep 10, 2003
DeadCow
August 31, 2003
In a situation
  class B:A { ... }
I can call
  foo(A a);
passing instances of class A or class B.

Now I would like to write a function
  foo(A [] atab)
that I can pass arrays of instances of A or B.
But I can't make it happen. It won't compile.

It's the same when I use interfaces.

My sample code (contains both trys):

    interface Printable {
      void print();
    }

    class A:Printable {
      void print() { printf("A\n"); }
    }

    class B:A {
      void print() { printf("B\n"); }
    }

    void Print(A a) {
      a.print();
    }

    void ArrayPrint(A a[]) {
      for(int i=0; i<a.length; i++) {
        printf("[%d]: ",i); a[i].print();
      }
    }

    void PrintablePrint(Printable p) {
      printf("via Interface: "); p.print();
    }

    void ArrayPrintablePrint(Printable [] p) {
      for(int i=0; i<p.length; i++) {
        printf("via Interface [%d]: ",i); PrintablePrint(p[i]);
      }
    }

    int main ()
    {
      A atab[];

      atab.length=3;
      atab[0]= new A;
      atab[1]= new A;
      atab[2]= new A;

      Print(atab[0]);
      ArrayPrint(atab);

      B btab[];
      btab.length=3;
      btab[0]= new B;
      btab[1]= new B;
      btab[2]= new B;

      Print(btab[0]);
      // ArrayPrint(btab); //  doesn't compile

      PrintablePrint(atab[0]);
      PrintablePrint(btab[0]);

      // ArrayPrintablePrint(atab); // doesn't compile
      // ArrayPrintablePrint(btab); // doesn't compile

      return 0;
    }

Shouldn't the 3 commented lines work?

-- 
Helmut Leitner    leitner@hls.via.at
Graz, Austria   www.hls-software.com
August 31, 2003
When you declare an array of class A[N], the compiler will allocate
N*sizeof(A) + a bit of memory for it. You cannot then store an element B
(derived from A) in that same array, since sizeof(B) is typically larger
than sizeof(A) which would confuse indexing calculations.

So basically, the case here is that A[] is a totally different type than B[], even though B may be derived from A. 'Type substitutionability' (somebody rephrase this :)as a result of inheritance does not apply to arrays

You would be able to create an array of _pointers_ to A, which could then point to instances of B as you like.

The answer to your question should thus be: feature

"Helmut Leitner" <helmut.leitner@chello.at> wrote in message news:3F524DD2.84943F44@chello.at...
> In a situation
>   class B:A { ... }
> I can call
>   foo(A a);
> passing instances of class A or class B.
>
> Now I would like to write a function
>   foo(A [] atab)
> that I can pass arrays of instances of A or B.
> But I can't make it happen. It won't compile.
>
> It's the same when I use interfaces.
>
> My sample code (contains both trys):
>
>     interface Printable {
>       void print();
>     }
>
>     class A:Printable {
>       void print() { printf("A\n"); }
>     }
>
>     class B:A {
>       void print() { printf("B\n"); }
>     }
>
>     void Print(A a) {
>       a.print();
>     }
>
>     void ArrayPrint(A a[]) {
>       for(int i=0; i<a.length; i++) {
>         printf("[%d]: ",i); a[i].print();
>       }
>     }
>
>     void PrintablePrint(Printable p) {
>       printf("via Interface: "); p.print();
>     }
>
>     void ArrayPrintablePrint(Printable [] p) {
>       for(int i=0; i<p.length; i++) {
>         printf("via Interface [%d]: ",i); PrintablePrint(p[i]);
>       }
>     }
>
>     int main ()
>     {
>       A atab[];
>
>       atab.length=3;
>       atab[0]= new A;
>       atab[1]= new A;
>       atab[2]= new A;
>
>       Print(atab[0]);
>       ArrayPrint(atab);
>
>       B btab[];
>       btab.length=3;
>       btab[0]= new B;
>       btab[1]= new B;
>       btab[2]= new B;
>
>       Print(btab[0]);
>       // ArrayPrint(btab); //  doesn't compile
>
>       PrintablePrint(atab[0]);
>       PrintablePrint(btab[0]);
>
>       // ArrayPrintablePrint(atab); // doesn't compile
>       // ArrayPrintablePrint(btab); // doesn't compile
>
>       return 0;
>     }
>
> Shouldn't the 3 commented lines work?
>
> -- 
> Helmut Leitner    leitner@hls.via.at
> Graz, Austria   www.hls-software.com


August 31, 2003
But D uses class references, which isn't the actual memory but a disguised pointer (?) so I think it should work. It would be a problem for structs, but they aren't allowed to have inheritance.

"Jeroen van Bemmel" <someone@somewhere.com> wrote in message news:bitnrj$204b$1@digitaldaemon.com...
> When you declare an array of class A[N], the compiler will allocate
> N*sizeof(A) + a bit of memory for it. You cannot then store an element B
> (derived from A) in that same array, since sizeof(B) is typically larger
> than sizeof(A) which would confuse indexing calculations.
>
> So basically, the case here is that A[] is a totally different type than B[], even though B may be derived from A. 'Type substitutionability' (somebody rephrase this :)as a result of inheritance does not apply to arrays
>
> You would be able to create an array of _pointers_ to A, which could then point to instances of B as you like.
>
> The answer to your question should thus be: feature
>
> "Helmut Leitner" <helmut.leitner@chello.at> wrote in message news:3F524DD2.84943F44@chello.at...
> > In a situation
> >   class B:A { ... }
> > I can call
> >   foo(A a);
> > passing instances of class A or class B.
> >
> > Now I would like to write a function
> >   foo(A [] atab)
> > that I can pass arrays of instances of A or B.
> > But I can't make it happen. It won't compile.
> >
> > It's the same when I use interfaces.
> >
> > My sample code (contains both trys):
> >
> >     interface Printable {
> >       void print();
> >     }
> >
> >     class A:Printable {
> >       void print() { printf("A\n"); }
> >     }
> >
> >     class B:A {
> >       void print() { printf("B\n"); }
> >     }
> >
> >     void Print(A a) {
> >       a.print();
> >     }
> >
> >     void ArrayPrint(A a[]) {
> >       for(int i=0; i<a.length; i++) {
> >         printf("[%d]: ",i); a[i].print();
> >       }
> >     }
> >
> >     void PrintablePrint(Printable p) {
> >       printf("via Interface: "); p.print();
> >     }
> >
> >     void ArrayPrintablePrint(Printable [] p) {
> >       for(int i=0; i<p.length; i++) {
> >         printf("via Interface [%d]: ",i); PrintablePrint(p[i]);
> >       }
> >     }
> >
> >     int main ()
> >     {
> >       A atab[];
> >
> >       atab.length=3;
> >       atab[0]= new A;
> >       atab[1]= new A;
> >       atab[2]= new A;
> >
> >       Print(atab[0]);
> >       ArrayPrint(atab);
> >
> >       B btab[];
> >       btab.length=3;
> >       btab[0]= new B;
> >       btab[1]= new B;
> >       btab[2]= new B;
> >
> >       Print(btab[0]);
> >       // ArrayPrint(btab); //  doesn't compile
> >
> >       PrintablePrint(atab[0]);
> >       PrintablePrint(btab[0]);
> >
> >       // ArrayPrintablePrint(atab); // doesn't compile
> >       // ArrayPrintablePrint(btab); // doesn't compile
> >
> >       return 0;
> >     }
> >
> > Shouldn't the 3 commented lines work?
> >
> > --
> > Helmut Leitner    leitner@hls.via.at
> > Graz, Austria   www.hls-software.com
>
>


September 01, 2003
"Jeroen van Bemmel" <someone@somewhere.com> ha scritto nel messaggio news:bitnrj$204b$1@digitaldaemon.com...
> [...] 'Type substitutionability' (somebody rephrase this :) [...]

Polymorphism, maybe?

Ric


September 01, 2003

Jeroen van Bemmel wrote:
> 
> When you declare an array of class A[N], the compiler will allocate N*sizeof(A) + a bit of memory for it.

I don't think so.

I think there is an array reference consisting of
   - array size
   - pointer to start of array
and the array of object reference
   - N * 4 byte of heap storage
and perhaps (if initialized)
   - N * sizeof(A) of heap storage for the instances

But I'm can't be quite sure about these implementation detail.

> You cannot then store an element B
> (derived from A) in that same array, since sizeof(B) is typically larger
> than sizeof(A) which would confuse indexing calculations.
> 
> So basically, the case here is that A[] is a totally different type than B[], even though B may be derived from A. 'Type substitutionability' (somebody rephrase this :)as a result of inheritance does not apply to arrays

If I cast:
  ArrayPrint( cast(A []) btab );
it compiles and works, but this type of casting seems very unsafe to me
(if I cast to the interface Printable it also compiles but <crashes>).

-- 
Helmut Leitner    leitner@hls.via.at
Graz, Austria   www.hls-software.com
September 01, 2003
> But I'm can't be quite sure about these implementation detail.

I'm not sure either, my posting was based on C++ semantics. Did you try the pointer-to-A array ?

>
> > You cannot then store an element B
> > (derived from A) in that same array, since sizeof(B) is typically larger
> > than sizeof(A) which would confuse indexing calculations.
> >
> > So basically, the case here is that A[] is a totally different type than B[], even though B may be derived from A. 'Type substitutionability' (somebody rephrase this :)as a result of inheritance does not apply to arrays
>
> If I cast:
>   ArrayPrint( cast(A []) btab );
> it compiles and works, but this type of casting seems very unsafe to me
> (if I cast to the interface Printable it also compiles but <crashes>).

Try adding a datamember to B and see if the casting still works.

>
> -- 
> Helmut Leitner    leitner@hls.via.at
> Graz, Austria   www.hls-software.com


September 01, 2003
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


September 02, 2003
Walter,

Could you add this information to the 'Arrays' section of the D webpages? It's counter intuitive (at least for C++ people like me) and it makes me give wrong answers :)

"Walter" <walter@digitalmars.com> wrote in 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
>
>


September 02, 2003

Jeroen van Bemmel wrote:
> 
> Walter,
> 
> Could you add this information to the 'Arrays' section of the D webpages? It's counter intuitive (at least for C++ people like me) and it makes me give wrong answers :)
> 

In addition there ar some new pages on Wiki4D
  <http://www.prowiki.org/wiki4d/wiki.cgi?NotesForProgrammersUsedTo>
  <http://www.prowiki.org/wiki4d/wiki.cgi?NotesForProgrammersUsedTo/CplusPlus>
so that we can gather hints or special considerations for the users of various
languages.

-- 
Helmut Leitner    leitner@hls.via.at
Graz, Austria   www.hls-software.com
September 02, 2003
I think that's a good idea. I'll do it when I fix that bug. I remember when I first was trying to learn Java I came to grief several times from forgetting that Java does objects by reference.

"Jeroen van Bemmel" <someone@somewhere.com> wrote in message news:bj1adh$tkl$1@digitaldaemon.com...
> Walter,
>
> Could you add this information to the 'Arrays' section of the D webpages? It's counter intuitive (at least for C++ people like me) and it makes me give wrong answers :)
>
> "Walter" <walter@digitalmars.com> wrote in 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
> >
> >
>
>


« First   ‹ Prev
1 2