[comp.sys.mac.programmer] Comments on THINK C 4.0

mce@tc.fluke.COM (Brian McElhinney) (08/15/89)

Some quick initial comments:

	1) The "THINK Class Library" looks great, but it is very large.  So
	   large that it obviously needs a browser; they must have decided it
	   was too much work for this release?  Grrr.  The hard part is
	   knowing which files to parse, and parsing them.  When you have
	   access to the THINK C sources the rest should be relatively easy.
	   It would have been a better example than a MacPaint-clone (but then
	   so would a MacDraw-clone -- how do you save and restore objects to
	   disk?  Lists of objects?).

	2) The new() operator does no type checking.  You would like for

		CMyApplication gMyApplication;
		...
		gMyApplication = new(CApplication);

	   to cause a compiler error, but it doesn't (this type of error can
	   be a good way to crash your machine).  It's obvious that it would
	   be non-trivial to catch, but shows a distinct advantage for C++
	   constructors (where you can't get this wrong; you also can't forget
	   to call the initialization method, as the above does).

	3) The Sample and Pedestal applications: both contain Draw() and
	   DoClick() routines with comments saying "put your code here".  That
	   works fine for Draw(), but DoClick() ends up in CView, as if it were
	   not overloaded.  I must be missing something obvious.  HELP!!

	4) It's deceptive to call it a C++ subset; the list of C++ features
	   not implemented encompasses nearly the entire C++ language!  It
	   does not have operator overloading, references, constructors,
	   destructors, private data, friends, inlines, or, of course, all
	   the version 2.0 features (multiple inheritance, etc).

	   Actually, you could say that the philosophy behind C++ is opposed
	   to that of the Macintosh.  Stroustrup has said that "features that
	   would incur run-time or memory overheads even when not used were
	   avoided".  Objects in handles are an obvious need for Macintosh
	   programs, and just as obviously heretical to the rest of the C++
	   community.

	5) It may not be C++, but it is very well matched to the needs of the
	   Macintosh programming community.  The object-oriented features
	   coupled with the THINK Class Library should be a wonderful
	   environment for developing Macintosh applications.

	6) Except for the lack of a &%*$# browser...
 
 
Brian McElhinney
mce@tc.fluke.com

jpd00964@uxa.cso.uiuc.edu (08/16/89)

/* Written  3:42 pm  Aug 14, 1989 by mce@tc.fluke.COM in uxa.cso.uiuc.edu:comp.sys.mac.programmer */
/* ---------- "Comments on THINK C 4.0" ---------- */
> Some quick initial comments:
>	2) The new() operator does no type checking.  You would like for
>
>		CMyApplication gMyApplication;
>		...
>		gMyApplication = new(CApplication);
>
>	   to cause a compiler error, but it doesn't (this type of error can
>	   be a good way to crash your machine). 

You do not want the new operator to do type checking like that.  It should 
be extremely easy to allow different objects to be assigned any variable.
For example, assume an object called holder.  Subtypes of Holder can be cup,
box, sack, etc.  Each of these have identically named routines that act
differently.  You should easily be able to have one variable that could be
any of those.

>	4) It's deceptive to call it a C++ subset; the list of C++ features
>	   not implemented encompasses nearly the entire C++ language!  It
>	   does not have operator overloading, references, constructors,
>	   destructors, private data, friends, inlines, or, of course, all
>	   the version 2.0 features (multiple inheritance, etc).

I think that was known for quite some time no matter how much smoke was blown
over this issue.  Claiming Upward compatable was so much Blown Smoke that it
almost made some people ill (me for one :->).  

>	   Actually, you could say that the philosophy behind C++ is opposed
>	   to that of the Macintosh.  Stroustrup has said that "features that
>	   would incur run-time or memory overheads even when not used were
>	   avoided".  Objects in handles are an obvious need for Macintosh
>	   programs, and just as obviously heretical to the rest of the C++
>	   community.

The Macintosh philosophy changes over time.  Some things will remain the same
forever, (such as mediocre to poor support for developers) but this aspect
will change.  Actually, OOP is very mac like.  The traps are almost (not the 
word almost) a precursor to OOP philosophy.  The actual routines were able
to be changed entirely transparent to the program.  This is the same for
OOP.

Michael Rutman
Softmed

duggie@Jessica.stanford.edu (Doug Felt) (08/17/89)

In article <227700029@uxa.cso.uiuc.edu> jpd00964@uxa.cso.uiuc.edu writes:
>
>/* Written  3:42 pm  Aug 14, 1989 by mce@tc.fluke.COM in uxa.cso.uiuc.edu:comp.sys.mac.programmer */
>/* ---------- "Comments on THINK C 4.0" ---------- */
>> Some quick initial comments:
>>	2) The new() operator does no type checking.  You would like for
>>
>>		CMyApplication gMyApplication;
>>		...
>>		gMyApplication = new(CApplication);
>>
>>	   to cause a compiler error, but it doesn't (this type of error can
>>	   be a good way to crash your machine). 
>
>You do not want the new operator to do type checking like that.  It should 
>be extremely easy to allow different objects to be assigned any variable.
>For example, assume an object called holder.  Subtypes of Holder can be cup,
>box, sack, etc.  Each of these have identically named routines that act
>differently.  You should easily be able to have one variable that could be
>any of those.

Actually, you don't want to assign an object to a variable whose type
is one of its subclasses, which is what the original example showed.
You would be tempted to access fields of the object variable that didn't
exist (assuming one has access in Think C 4.0), or call methods that
weren't implemented for that object.  

Your (implied) counterexample is not a true one, because to do what
you describe, one assigns an object to a variable whose type is one of
the object's superclasses.  Accesses through this variable will always
be valid, as the fields and methods of the superclass are always
defined in the subclass.

I believe Object Pascal restricts assignments in one direction but not
the other.  I am not sure but I think the assignment is a runtime
restriction, in that code is generated to check the class of the
object being assigned and test this against the class of the variable.
Thus 'new' is not doing the work, and the restriction applies no matter
where the object came from.

Perhaps the reason this restriction wasn't implemented is because it
was doubly damned, as being both a runtime penalty and a crutch for
programmers who can't handle C.  Me, I prefer all the assistance the
compiler can give me, but a lot of C programmers are proud of having 
learned to live on the edge... :-)

>Michael Rutman
>Softmed

Doug Felt
Courseware Authoring Tools Project
duggie@jessica.stanford.edu

mce@tc.fluke.COM (Brian McElhinney) (08/19/89)

In article <227700029@uxa.cso.uiuc.edu> jpd00964@uxa.cso.uiuc.edu writes:
>You do not want the new operator to do type checking like that.  It should 
>be extremely easy to allow different objects to be assigned any variable.
>For example, assume an object called holder.  Subtypes of Holder can be cup,
>box, sack, etc.  Each of these have identically named routines that act
>differently.  You should easily be able to have one variable that could be
>any of those.

No, you must be restricted to the same or sub-classes, not just any class:

    struct thing {
        int value;
    };
    struct sub_thing : thing {
        int thing_value;
    };
    bug()
    {
        thing *t;
        sub_thing *st;

        t = new(thing);
        st = new(sub_thing);
        t = new(sub_thing);             /* valid polymorphism 		     */
        st = new(thing);                /* ERROR: incompatible pointers      */
        st = (sub_thing *)new(thing);   /* run time error: no space reserved */
                                        /* for st->thing_value 		     */
    }

The compile time error is not caught by THINK C 4.0, leading to the related
run time error.

THINK C 4.0 is a wonderful product (thanks guys!), that has some slight
syntactical similarities to C++.  Period.  Inheritance isn't the same as C++,
because the type checking is different.
 
 
Brian McElhinney
mce@tc.fluke.com
 
 
PS: the Starter and Pedestal examples have an error in the comments.  Where it
says "if you want to handle mouse events, put your code here" (paraphrased), it
should also mention that you must SetWantsClicks(TRUE) in the initialization
method for the pane.

lsr@Apple.COM (Larry Rosenstein) (08/21/89)

In article <4590@portia.Stanford.EDU> duggie@Jessica.UUCP (Doug Felt) writes:
>
>I believe Object Pascal restricts assignments in one direction but not
>the other.  I am not sure but I think the assignment is a runtime
>restriction, in that code is generated to check the class of the
>object being assigned and test this against the class of the variable.
>Thus 'new' is not doing the work, and the restriction applies no matter
>where the object came from.

It is always safe to assign an object of a subclass type to a variable of an
ancestor type.  That's because an instance of a subclass can always be
treated like an instance of any of its ancestor classes.  For example, if
you have class Container and subclasses Box, Jar, ... it is always legal to
treat an instance of Box, Jar, ... as if it was an instance of Container.

It is not safe to to the opposite thing.  Given an instance of Container,
you can't always treat it as an instance of Box.  (It may be an instance of
Jar, for example.)  

Object Pascal does not allow you to make the assignment directly.  You have
to cast the object to the proper type.  The cast generates code to check the
validity of the types, when range checking is turned on.  (The compiler does
a similar thing with array bounds checking.)  When a program is being
developed, the code is compiled in and will give a run-time error.
Production programs are normally built without range-checking code, and the
casts generate no extra code.

Object Pascal does not run into the same problem when creating an object,
because the syntax is different.  You write 'New(anObject)' where anObject
is declared to be a class type.  The object created exactly matches the type
of the variable, so there is no issue.
		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 46-B  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr

flanagan@apollo.HP.COM (Kevin Flanagan) (09/08/89)

I may have missed this but...I've got THINK C 3.x and I sent
in the registration card, etc.  Shouldn't I have gotten an
upgrade notice??  Or is 4.0 not generally available yet?

Thanx,
Kevin (flanagan@apollo.com)