caw@munnari.oz.au (Chris Wright) (03/04/91)
I've been doing some tinkering in THINK C, in particular trying to work out the binding strategy. I enclose some code which shows some interesting aspects of the systems behaviour. It seems to perform dynamic binding for some function calls, but exhibits static behaviour on other occasions. Any comments? chris /* The point of these classes is that the function trickyFnSuper() in the superclass calls classFn (which has a definition both in the subclass and in the superclass). From the behavior, it would appear that the there is RUNTIME binding of the correct classFn(). I think this is what the "virtual" keyword in C++ accomplishes. More interesting, however, is the behaviour of the myToBeCast variable. This starts out in life as a member of MySuperClass, but then gets assigned to new(MySubClass). When the myToBeCast -> trickyFnSuper() is evaluated, there is still the correct "runtime" binding to the subclasses' ClassFn. However, if we try to compile myToBeCast->uniqueToSubFn(), the compiler chokes. I guess this is because we are looking a COMPILE time behaviour, and not RUNTIME behaviour. The compiler thinks that myToBeCast is a member of the superclass for the purposes of method compilation. If you cast myToBeCast : (MySubClass *) myToBeCast -> uniqueToSubFn() then all is sweetness and light. How come the compiler is smart enough to allow runtime (or dynamic) binding to the subclasses methods, but not smart enough to know that myToBeCast is now a member of the subclass?????? */ #include <stdio.h> #include <oops.h> struct MySuperClass : indirect { MySuperClass *classInit(void); int classInt; int classFn(int); int trickyFnSuper(int); }; struct MySubClass : MySuperClass { int classFn(int); int uniqueToSubFn(int); }; int MySuperClass::classFn(i) int i; { return i + 1; } MySuperClass *MySuperClass::classInit(void) { classInt = 2; return this; } int MySuperClass::trickyFnSuper(i) int i; { int j; j = classFn(i); return j; } int MySubClass::classFn(i) int i; { return i + 10; } int MySubClass::uniqueToSubFn(i) int i; { return i + 100; } MySuperClass *mySuperInstance; MySuperClass *myToBeCast; MySubClass *mySubInstance; main() { mySuperInstance = new(MySuperClass) ; myToBeCast = new(MySubClass); mySubInstance = new(MySubClass); mySuperInstance -> classInit(); printf("%d\n", mySuperInstance->classFn(3)); /* ->4 */ printf("%d\n", mySuperInstance->classInt); /* ->2 */ printf("%d\n", mySuperInstance->trickyFnSuper(1)); /* ->2 */ printf("%d\n", mySubInstance->trickyFnSuper(1)); /* ->11 */ printf("%d\n", myToBeCast->trickyFnSuper(1)); /* ->11 */ printf("%d\n", mySubInstance->uniqueToSubFn(1)); /* ->101 */ /* printf("%d\n", myToBeCast->uniqueToSubFn(1)); -----CHOKES----*/ printf("%d\n", ((MySubClass *) myToBeCast)->uniqueToSubFn(1)); /* ->101 */ } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% chris wright - a guest on melbourne university if the mail bounces, try caw@munmurra.cs.mu.oz.u
Lawson.English@p88.f15.n300.z1.fidonet.org (Lawson English) (03/06/91)
Chris Wright writes in a message to All you cast myToBeCast : (MySubClass *) myToBeCast -> uniqueToSubFn() CW> then all is sweetness and light. How come the compiler is smart CW> enough to allow runtime (or dynamic) CW> binding to the subclasses methods, but not smart enough to know CW> that myToBeCast is now a member of the subclass?????? Because it's not very smart? Seriously, do you know of any compiler that keeps track of type-casting? IE, if you do a "(char*) myInt", do you expect the compiler to remember that myInt was just used as (*char)? If not (and I'd love to see the headaches that THAT would cause if you found a compiler that would actually do it), why do you expect a compiler to remember the typecast for an object? I suppose that it could be built-in, simply for objects, but that sounds like pretty un-documentable behavior to me... Lawson -- Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!300!15.88!Lawson.English Internet: Lawson.English@p88.f15.n300.z1.fidonet.org