[comp.lang.c++] virtual static data?

roger@procase.UUCP (Roger H. Scott) (05/25/90)

AT&T has been aware of interest in virtual data members for some time now.
Other than it not being an "urgent" issue, one of the problems is the semantics
of non-static virtual data members - what do they mean?  It would be pretty
ugly to exclude them from the paradigm.  Personally I hope we live to see the
day when virtual/non-virtual, static/non-static, and data/function are all
completely orthogonal for members.  How 'bout it, ANSI committee?

roger@procase.UUCP (Roger H. Scott) (05/25/90)

In article <13757@csli.Stanford.EDU> Neil Hunt <Neil%teleos.com@ai.sri.com> writes:
>raeburn@athena.mit.edu (Ken Raeburn) writes:
>>Is there a logical reason for disallowing virtual static data members?
>This is a feature I have also wanted.  One problem is that static members
>are supposed to be able accessible without an object by using the qualifier.
>But then there is no vtable from which to do the virtual lookup.

This is the same misguided argument made against virtual static member functions
a month or two ago on the net - and it is wrong for exactly the same reasons.
If I refer to any virtual feature of a class with a qualified reference (c::f)
I have de-virtualized it - the "correct" class is provided explicitly in the
qualifier, thus there is no need for a vptr.

roger@procase.UUCP (Roger H. Scott) (05/26/90)

In article <54856@microsoft.UUCP> jimad@microsoft.UUCP (Jim ADCOCK) writes:
>...
>The implied complaint being that virtual functions are slower than virtual
>static data members?  -- This need not be the case.  Or are you worried about
>typing pfoo->classname(); verses pfoo->classname; ???

Speed is *an* issue, but not *the* major issue.  Virtual static data members
require only space enough for a slot in the vtbls plus the space for the data
itself in those classes that redefine the data; a virtual function returning
the same value requires a vtbl slot, the space for the data, *plus* the space
for the code for the function (small, but positive).  It is also inconvenient
to have to define both the function and the data when all I want is the data.
Lastly, virtual data is appealing to people like me who think orthogonality is
a GOOD THING in a language.

jimad@microsoft.UUCP (Jim ADCOCK) (05/31/90)

In article <1990May25.003734.24552@athena.mit.edu> Ken Raeburn <Raeburn@MIT.Edu> writes:
>I dislike the idea of being forced to use a function call to retrieve a
>piece of data that should be treated as static and virtual and const, and
>_will always be simple data_.  In the case I have in mind, the functions I
>have to write for this class (and those derived from it) to do this will
>never do anything but return this one constant value.  If it were
>otherwise, it would make sense to require a function, since some unforseen
>new class might want to do computation to produce the results; that isn't
>the case here.

The only thing forcing you to use function calls to retrieve a piece of data
is the fact that present day C++ compilers are not yet up to the level of
quality required to really support object oriented programming.  People are
still trying to use C optimization techniques in C++ compilers -- 
the optimization issues are just not the same.

Other OOPLs allow a programmer to say "foo" when either accessing a piece
of data or calling a function with no parameters -- the compiler automatically
handles the difference.  When a programmer says "foo(bar)" a function call
is [typically] made.  Whether or not the methods are overridden in sub-classes.

Since in C++ for versioning reasons and strict encapsulation serious 
programmers desire to hide whether a particular member is implemented
as a member variable, or as a member function, the convention has become always
use parenthesis -- C++ programmers always say "foo()" whether foo is really 
implemented as a function call or as an inline function short-circuiting
to a member variable access.  At least if "foo()" is part of the public
interface.

If other OOPL compilers are smart enough to optimize "foo" to mean either
a variable look-up or a function call depending on the circumstances, why
cannot C++ compilers be smart enough to optimize "foo()" to be either a
variable look-up or a function call depending on the circumstances?
[whether or not foo is virtual]

-- Clearly they can!  They just don't, yet.  One hang up is the notion that
virtual-ness needs to be handled via vtables.  It needn't.  Another hang-
up is the traditional Unix/C model of separate compilation/linking.  Without
knowledge of what your children might be doing, its hard [not impossible]
to avoid doing a full blown virtual function dispatch when only a "virtual
static member" is needed.  If a compilation/link system has complete knowledge
of what children are doing, then clearly as part of a final optimized compile
and link [for shipment, say] the system can say "foo() is never overridden
to mean anything other than a 'virtual static member', thus I need not 
implement foo() as full-blown virtual function dispatches."

Adding static member variables to the language would encourage people
"for efficiency reasons" to make them part of the public interface.  This
would force designers to make hard and fast decisions between whether to
offer "foo" or "foo()" as the public interface, thus constraining future
choices, and leading to a constant confusion among users of classes as
whether to use "foo" or "foo()" when messaging an object of this class.

Let's continue to use function syntax for all public interfaces -- even
though I agree it would have been nice if C hadn't already forced this
convention.  Let's not continue to add obscure syntax to help mediocre
compilers optimize uncommon code slightly.

mike@taumet.COM (Michael S. Ball) (05/31/90)

In article <54945@microsoft.UUCP> jimad@microsoft.UUCP (Jim ADCOCK) writes:
>The only thing forcing you to use function calls to retrieve a piece of data
>is the fact that present day C++ compilers are not yet up to the level of
>quality required to really support object oriented programming.  People are
>still trying to use C optimization techniques in C++ compilers -- 
>the optimization issues are just not the same.

Actually, the real limitation is the very stupid environments in which
C++ program development takes place.  I mean that the environments lack
built-in intelligence, not that they are stupidly defined.  They worked
fine for developing C.  We seriously looked at a number of optimizations
for our C++ frontend, and had to give them up because the logistics became
unmanagable in most of the environments our customers wanted.

>If other OOPL compilers are smart enough to optimize "foo" to mean either
>a variable look-up or a function call depending on the circumstances, why
>cannot C++ compilers be smart enough to optimize "foo()" to be either a
>variable look-up or a function call depending on the circumstances?
>[whether or not foo is virtual]

Only because it requires more global data than is available in most programming
environments.  On the other hand, even virtual function calls can be
very cheap if properly implemented.

>-- Clearly they can!  They just don't, yet.  One hang up is the notion that
>virtual-ness needs to be handled via vtables.  It needn't.

No, but it's an effecient implementation which requires no global knowledge.

>							     Another hang-
>up is the traditional Unix/C model of separate compilation/linking.  Without
>knowledge of what your children might be doing, its hard [not impossible]
>to avoid doing a full blown virtual function dispatch when only a "virtual
>static member" is needed.

In a true polymorphic situation it can't be avoided without SOME knowledge
of what your children are doing.  In many situations the true type can be
computed at compile time, and you should expect a compiler to do this.  With
enough global knowledge you can specialize routine calls and generate inline
code even with virtual functions.  By the way, a "full blown virtual function
dispatch" isn't necessarily expensive, it just gets that way when you have
to go through C.

>Let's continue to use function syntax for all public interfaces -- even
>though I agree it would have been nice if C hadn't already forced this
>convention.  Let's not continue to add obscure syntax to help mediocre
>compilers optimize uncommon code slightly.

AMEN!

Please note, I support the development of environments which would let
a C++ system do a good job, but I think that a great deal of C++'s
success is due to it's ability to fit into C environments with a minimum
of fuss.  Big environments are expensive to develop and move, so will
only come into existance when the demand justifies it.  C++ is starting
to get there, but isn't yet.

Mike Ball			mike@taumet.com
TauMetric Corporation

mat@mole-end.UUCP (Mark A Terribile) (06/09/90)

In article <151@logo.procase.UUCP>, roger@procase.UUCP (Roger H. Scott) writes:
> AT&T has been aware of interest in virtual data members for some time now.
> Other than it not being an "urgent" issue, one of the problems is the semantics
> of non-static virtual data members - what do they mean?  It would be pretty
> ugly to exclude them from the paradigm.  Personally I hope we live to see the
> day when virtual/non-virtual, static/non-static, and data/function are all
> completely orthogonal for members.  How 'bout it, ANSI committee?



The main ``virtual data'' improvement I would like to see is to allow
a derived class to redefine a pointer in the base class:

	class	Base
	{
		. . .
		virtual Base* my_link;
		Base1* their_link;
		. . .
	};
	
	class	Derived
	{
		. . .
		// Base::my_link is redefined as  Derived*  here ...
		Derived1* Base::their_link;	// and Base1* is used
						// as Derived1* here
		. . .
	};


This may require some way of forward-declaring the inheritance relationshps,
but it would allow linked structures to be written into the base classes and
either automatically or deliberately redefined within the hierarchy.  Such
operation is not unlike the handling of  this .  It would require playing
some offset games, and would probably not work around virtual MI.  I *think*
it could be done in all other cases.

At least once a week I wish for this capability ... and I would even like
to be able to declare a pointer that would automatically take on the most
derived type ...

Somehow, I think this would really help the OOPing.
-- 

 (This man's opinions are his own.)
 From mole-end				Mark Terribile