Topic: ANSI draft bug and subsequent compiler


Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Wed, 22 Jun 1994 21:27:01 GMT
Raw View
In article <2t7ji5$7fs@engnews2.Eng.Sun.COM> clamage@taumet.Eng.Sun.COM writes:
>implementations to solve. Arrays must be of homogeneous objects, not
>polymorphic objects. (You can have an array of pointers to polymorphic
>objects, but the array is of a single pointer type.)

 Excuse picking at terminology. The 'opposite'
of 'homogenous' is 'heterogenous'. The 'opposite' of
'homomorphic' (means 'one structured') is 'heteromorphic'
(many structured).

 'Polymorphism' ought to mean the same as heteromorphism
but it DOESNT technically.  It actually mandates homogeneity
of the interface (public state of the object) but allows
heterogenous representations.

 Arrays require homogenous representations.
You can have arrays of polymorphic objects. No problem.
What you meant was you cant have heterogenous arrays:
arrays of different (representation) types of objects.

 In fact, in C++ static checking requires ALL
interfaces to be homogenous. You cant have heterogenous
lists either.

 Thats why, for example, there are unions.
A union is a type unifier -- it takes several different
types and makes a single unified type which you CAN
put into an array.

 Can you have arrays of objects of different types?
No. Yes.  Depends whether an array of

 union number { int a; long b; };

is considered an array of number objects (homogenous)
or an array of objects which might be either an int or a long.
(heterogenous)

 There are three (at least :-) fundamental
operations:

 a) type unification: a union is the union of the
 objects of each of the component types
 -- the converse of unification is discrimination
 or selection (in C that means a switch)

 b) subtyping: a subtype is a subset of the
 objects of the base type; consequence: polymorphism

 c) composition/product: the product type is
 the cartesian product of the types: consequence:
 interface addition

Inheritance, perhaps unfortunately, is a mechanism which
can do either (b) or (c) or both at the same time.
And when it does (c) it may appear as if it can do
(a) using derived-->base conversions.

This is a serious abuse. It cant unify types without RTTI.
Derived to base conversions do slicing -- which is another mechanism:

 d) equivalence class formation

in which for example red and blue points at the origin are identified
as a point at the origin. This operation is just the opposite
of product formation (its called the quotient operation in maths :-)

This 'unifies' STATE and not TYPE: the derived type is NOT
a subtype, but the equivalence classes (sliced objects)
may be a subtype of the base (usually isomorphic, that is,
an improper and equal subset).

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: clamage@taumet.Eng.Sun.COM (Steve Clamage)
Date: 9 Jun 1994 17:29:41 GMT
Raw View
In article sau@highway.LeidenUniv.nl, rcenteno@iris (Rick Centeno (guest account)) writes:
>Hi,
>
>Can anyone tell me whether the following paragraph exerted from the
>ANSI draft standards of 25 Jan 94 makes sense?
>
>"In the second alternative, i.e.
>        delete[] Objects;
>if the dynamic type of the object to be deleted is a class that has a
>destructor and its static type is different from its dynamic type, the
>result is undefined."
>
>I have the distinct feeling that it should read "....a class that has NOT
>a (VIRTUAL) destructor and its static type....".

No, it is correct as worded. Consider the meaning of
 T* Objects;
 ...
 delete[] Objects;
This says that Objects points to an array of things of type T. Therefore,
the first operation is to step through the array destroying all objects.
So in pseudo-code the compiler must generate:
 int count = 0;
 T* p = Objects;
 while( count++ < number_in_array ) {
  p->~T();    // destroy object
  p = (T*) ((char*)p + sizeof(T)); // step thorugh array
 }
If the type pointed to by Objects isn't really T and has some other size,
how do we find that out? What stride length do we use for stepping
through the array?

This problem is not insoluble, but was judged not worth requiring all
implementations to solve. Arrays must be of homogeneous objects, not
polymorphic objects. (You can have an array of pointers to polymorphic
objects, but the array is of a single pointer type.) You allocate an
array of objects of one type, assign it to a pointer of that type,
then use that pointer (or a copy) when it is time to delete the array.
---
Steve Clamage, stephen.clamage@eng.sun.com