Topic: static virtual: Public Comment


Author: bill_law@taligent.com (William A. Law)
Date: 1995/07/10
Raw View
> The result is the same in all cases for what I believe is
> usually proposed for virtual static member functions.
>
> ---
> Steve Clamage, stephen.clamage@eng.sun.com

The result is not the same in the case of the specific "proposal" being
discussed.  Specifically, item (2) suggests that static virtual functions
resolve to the most-derived class's implementation during base class
construction.

Bill Law





Author: donorgan@ix.netcom.com (Don Organ)
Date: 1995/07/08
Raw View
In <3tk519$lke@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM (Steve
Clamage) writes:
>
>In article 1342@ittpub, wil@ittpub.nl (Wil Evers) writes:
>>In article <3tehem$54j@crcnis3.unl.edu> ebiederm@cse.unl.edu (Eric
>>Biederman) writes:
>>
>>... Static virtual functions, to me, would
>>implement semantics you can't currently express in C++. They are:
>>
>>- virtual, so the resolution of the call depends on the dynamic type
of
>>the object through which they are called (if present).
>>- static, so the compiler can guarantee the function called doesn't
>>directly access any non-static members.
>
>I believe you can get that functionality by having a virtual function
>call a static member function of its own class, without adding
>virtual static functions to the language.
>
>class Base {
>public:
> static T virt_stat(); // T is some type
> virtual T virt_static() { return virt_stat(); }
>};
>
>class Derived : public Base
>{
>public:
> static T virt_static(); // new version for this class
> virtual T virt_static() { return virt_stat(); } // override
>};
>
>Base* pb = new Derived;
>T t = pb->virt_static(); // calls Derived::virt_stat
>
>If you don't have an object, you just call the static version of the
>function. The result is the same in all cases for what I believe is
>usually proposed for virtual static member functions.
>
>---
>Steve Clamage, stephen.clamage@eng.sun.com
>
>

Perhaps I've had an unstated premise - that C++ should be sufficiently
robust that it can be applied to large, commercial projects.
A recent Scott Meyers' posting questioned whether the standard
could/should be changed such that the potential for a couple of
classes of fairly common programmer errors could be eliminated.
I agree with this attitude - I'd like to see fewer gotcha's in C++.

Of coarse your 2 function example works. My concern however, is that
it can be easily mis-applied by a programmer and such misuse is
difficult to detect. Here's a re-statement of your example from my
formal public comment on this topic:
 struct B {
  static void f();
  virtual void Vf() { f(); };
 };
 struct D : public B {
  static void f();
  virtual void Vf() { f(); };
 };
 void X(B *p) {  // p* might be B or D
  B::f(); // OK
  D::f(); // OK
  p -> Vf();  // OK
  p -> f();  // Hard-to-find programmer error:
     // WRONG if p* is a D!
     // B::f() is called, we
     // wanted D::f()
 }
This code may even appear to work properly for months or years.
It might not fail until somebody derives a struct E from D where
E::f() is sufficiently different from B::f() and D::f(). A time-bomb.
The other alternative (probably used more often), is to simply
implement a single (nonstatic) virtual member function. Of coarse, the
B::f() syntax doesn't work here. But probably more significant is the
opportunity (temptation) of a maintenance programmer to access
nonstatic members - this may pollute a design intent of the
function to provide a class-only service i.e. be "object ignorant"
(that sounds like flame-bait! :>)

Of coarse, you and I and any of the other advanced C++ programmers
who read this newsgroup wouldn't make such mistakes. But on a
project employing dozens of programmers (not all are C++ experts),
this is one more coding guideline to document and teach, one more
idiom that must be learned and one more opportunity for an error.
By itself, static virtual member functions certainly won't make or
break a project, but it is relevent to some real designs and the
lack of the capability is an inconsistency in the language.

I sense that many in this newsgroup see C++ more as a
prototyping/research language, where quick development (by
a small team) and efficient execution characteristics are
paramount. I respect those needs, but I bring a different
perspective (one that I haven't seen reflected often in this
newsgroup the past several months).

BTW Steve, your postings have answered many people's questions in a
consistently clear and concise manner - I've certainly learned from
several of them. This is not a forum where one often gets thanked,
but "Thanks!".

Don Organ






Author: scjones@thor.sdrc.com (Larry Jones)
Date: 1995/07/09
Raw View
In article <3t710o$e1a@News1.mcs.net>, jim.fleming@bytes.com (Jim Fleming) writes:
> It looks like many of the people on the ANSI C and ANSI C++ committees
> are the same. If (or when) the two languages converge, it is likely that
> those people that are common to both efforts will have the most influence.
> You might want to look into the ANSI C work also to make sure that you
> are part of the "inside activity" of that process.

On the contrary, there is very little overlap.  Nor is there any desire,
as far as I know, within either committee to merge the two languages.
----
Larry Jones, SDRC, 2000 Eastman Dr., Milford, OH  45150-2789  513-576-2070
larry.jones@sdrc.com
He just doesn't want to face up to the fact that I'll be
the life of every party. -- Calvin





Author: dag@net.dynasim.se (Dag Bruck)
Date: 1995/07/06
Raw View
In article <3tehem$54j@crcnis3.unl.edu>,
Eric Biederman <ebiederm@cse.unl.edu> wrote:
>
>>>You haven't investigated what 1) and 2) would require.  You can't just
>>>take out restrictions; you need to completely fill in all consequences
>>>of your changes, so that the resulting language will be well-defined.
>
>>Please don't dismiss static virtual data out of hand.

It seems to me that this confused discussion should be ended by someone
actually wrting the proposal and submitting it.  I encourage you to
seek the help from people who read comp.std.c++ to make the proposal as
good as possible.  With the help of a well-written proposal the discussion
could become more focused.

In particulat, I would like to see some examples that demonstrate why
this is an essential feature that cannot be (easily) provided with
existing language features.

>The problem is that seems to introduce another unituitive feature to the
>language and another pitfall.

That is my gut feeling too, but I'm willing to be convinced otherwise.

Dag Bruck
Member of ANSI X3J16 and ISO WG21
--
Dynasim AB                            Phone:  +46 46 182500
Research Park Ideon                   Fax:    +46 46 129879
S-223 70 Lund                         E-mail: Dag@Dynasim.se
Sweden





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/06
Raw View
In article 97q@akropolis.malmo.trab.se, dag@net.dynasim.se (Dag Bruck) writes:
>
>It seems to me that this confused discussion should be ended by someone
>actually wrting the proposal and submitting it.  I encourage you to
>seek the help from people who read comp.std.c++ to make the proposal as
>good as possible.  With the help of a well-written proposal the discussion
>could become more focused.
>
>In particulat, I would like to see some examples that demonstrate why
>this is an essential feature that cannot be (easily) provided with
>existing language features.

Yes. For example, such a proposal should show why a virtual function with
its own static data member doesn't solve the problems you intend to solve
with virtual static data members. You get one copy per class type in
the program, and the version of the data to be accessed is determined
by the virtual function call mechanism.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: wil@ittpub.nl (Wil Evers)
Date: 1995/07/07
Raw View
In article <3tehem$54j@crcnis3.unl.edu> ebiederm@cse.unl.edu (Eric
Biederman) writes:

[snip]

> The only use a static virtual function would have is if it could be
called
> inside constructurs of a base class, or if their addresses could be
taken
> dynamically and they could be assigned to regular function pointers.

Why is this the *only* use? Static virtual functions, to me, would
implement semantics you can't currently express in C++. They are:

- virtual, so the resolution of the call depends on the dynamic type of
the object through which they are called (if present).
- static, so the compiler can guarantee the function called doesn't
directly access any non-static members.

In other words, static virtual functions are capable of providing
class-related information depending on the actual type of an object.

> 1) The questions in my mind go how would you implement them?
>
> [snip]
>
> To implement them so that they will work in constructors requires that
they set
> up the virtual function table before the object is constructed.  That
doesn't
> look to hard to me, and which function is called in a regular virtual
context
> is well defined so it should not be too difficult.

By saying 'so that they work in constructors' I assume you mean that a
static virtual call would resolve to the most derived version when invoked
from a base class constructor (Don Organ's proposal #2).

In my opnion, that would be a bad mistake. It would be a clear exception
to the way non-static virtual calls are handled, and users would have to
know and worry about this. The only possible implementation of this rule I
can think of would require objects with non-static and static virtual
members to have two vtbl pointers: one that's set up just after the object
is allocated (for static virtuals) and one that's first set up just before
the base class constructor is entered and then re-assigned before a
derived class constructor is entered (for non-static virtuals).

> A disadvantage of that approach is that it requires classes that have no
normal
> virtual members functions to have the overhead of virtual functions, but
not
> having a this pointer simplifies things a lot.

Any object of a class that has virtual member functions, static or not,
must have a vtbl pointer. I think this overhead is quite acceptable, as it
only affects users who need them.

> Implementing pointers to these functions would be interesting.  As they
are
> virtual functions the _must_ have an object to resolve their virtualness
by
> the current definition of virtual functions.  This implementation
stresses
> their virtualness much more then their stacness.

As proposed, static virtual member functions *may* be called through an
object, they don't have to:

class X {
public :
 static virtual char *foo() { return "bar"; }
};

f(X *xObj)
{
 cout << X::foo() << endl; // always prints 'bar'
 cout << xObj->foo() << endl; // output depends on type of
     // what *xObj points to
}

Because there may not be an object and the this pointer is not passed,
pointers to static virtual member functions can't be implemented as
pointers to virtual member functions. Probably the most straightforward
thing to do would be to say that taking the address of a static virtual
member function results in a regular function pointer, and resolve them
when their address is taken:

g(X *xObj)
{
 char *(*pf1)() = X::foo; // always resolves to X:foo
 char *(*pf2)() = xObj->foo; // get address from xObj's vtbl
}

[snip]

- Wil





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/07
Raw View
In article 1342@ittpub, wil@ittpub.nl (Wil Evers) writes:
>In article <3tehem$54j@crcnis3.unl.edu> ebiederm@cse.unl.edu (Eric
>Biederman) writes:
>
>... Static virtual functions, to me, would
>implement semantics you can't currently express in C++. They are:
>
>- virtual, so the resolution of the call depends on the dynamic type of
>the object through which they are called (if present).
>- static, so the compiler can guarantee the function called doesn't
>directly access any non-static members.

I believe you can get that functionality by having a virtual function
call a static member function of its own class, without adding
virtual static functions to the language.

class Base {
public:
 static T virt_stat(); // T is some type
 virtual T virt_static() { return virt_stat(); }
};

class Derived : public Base
{
public:
 static T virt_static(); // new version for this class
 virtual T virt_static() { return virt_stat(); } // override
};

Base* pb = new Derived;
T t = pb->virt_static(); // calls Derived::virt_stat

If you don't have an object, you just call the static version of the
function. The result is the same in all cases for what I believe is
usually proposed for virtual static member functions.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: schuenem@informatik.tu-muenchen.de (Ulf Schuenemann)
Date: 1995/07/04
Raw View
In article <3stcjt$72c@ixnews6.ix.netcom.com>, donorgan@ix.netcom.com (Don Organ) writes:
[..]
To continue my previous answer:
|>     - (optional) short comments related to D&E section 6.4.1 (Criteria)
[..]
|>         rationale - why needed? who is audience? what kind of
|>             programming/design styles would this support? other
|>             languages with this feature?

virtual static can provide information about the actual class of the
object like: dyn_sizeof, memmoveable, memcopyable, numinstances ...
You can write more smoothly:
 A::memmoveable();
 a.memmoveable();
As opposed to
 A::stat_memmoveable();
 a.dyn_memmovable();

Before the introduction of RTTI "virtual static const char*className();"
was the best example. Now the is the danger that type_info is missused
to achieve something similar to virtual static.
(I can remember suggestions in this newsgroup that wanted to extend
type_info to contain several other infos about the class. As this
info is not in type_info, there is the danger, that type_info is
missused):

 size_t dyn_sizeof (myObj*o)
 { type_info ti = typeof(o)
  if(ti == typeof(myObj))
   return sizeof(myObj);
  else if(ti == typeof(myDerived1))
   return sizeof(myDerived1);
  else ...
 }

I'll think we can agree that this is BAD style.

|>         compatibility with existing code? (I believe #1 would no
|>             impact, I need help with #2 and #3).

Ad #1:
The following code is illegal:
 A *ap=NULL;
 ap->virt_static_memfkt();
But this can't break old code, as there is no virtual static in old code.
It only can cause problems when you change a former nonvirt static to
a virt one.

Contra #2: Such a decision would not fill a hole but would be a new
unothogonality in the resoultion of virtual memfkt. Without
reagarding the advantages, IMO this is too severe for the current state
of the standard process.

Contra #3: virtual static DATA (as dynamic binding in general) would only be
of use, if you can override it. Overriding datamembers would be a very new
feature in C++. I think this kills such considerations for the current
standard process.


Ulf Schuenemann

--------------------------------------------------------------------
Ulf Sch   nemann
Fakult   t f   r Informatik, Technische Universit   t M   nchen, Germany.
email: schuenem@informatik.tu-muenchen.de





Author: george@mvp.com (George Mitchell)
Date: 1995/07/04
Raw View
schuenem@informatik.tu-muenchen.de (Ulf Schuenemann) writes:

>Contra #3: virtual static DATA (as dynamic binding in general) would only be
>of use, if you can override it. Overriding datamembers would be a very new
>feature in C++. I think this kills such considerations for the current
>standard process.

The addresses of the virtual member functions of a class are virtual
static data.  Overriding works just fine for this virtual static data
already.  It is not at all a new feature.  In the case where virtual
functions are implemented by means of a vtable, all you have to do is
allow the vtable to contain data members.

>Ulf Schuenemann

-- George Mitchell (george@mvp.com)





Author: george@mvp.com (George Mitchell)
Date: 1995/07/04
Raw View
jbuck@synopsys.com (Joe Buck) writes:

>donorgan@ix.netcom.com (Don Organ) writes:

>>    3) Allowing static virtual data (and possibly nonstatic virtual
>>        data). I haven't investigated what changes to the draft
>>        this would require.

>You haven't investigated what 1) and 2) would require.  You can't just
>take out restrictions; you need to completely fill in all consequences
>of your changes, so that the resulting language will be well-defined.

Please don't dismiss static virtual data out of hand.  It already
exists: The addresses of the virtual member functions of a class
are static (per-class rather than per-instance) and virtual (deter-
mined in the basis of the type of an object, rather than the type
of the pointer), and they are data.

For those compilers which implement virtual functions by means of a
vtable, it is trivial to allow the vtable to contain data other than
the addresses of the member functions of the class.

-- George Mitchell (george@mvp.com)





Author: ebiederm@cse.unl.edu (Eric Biederman)
Date: 1995/07/05
Raw View
george@mvp.com (George Mitchell) writes:

>jbuck@synopsys.com (Joe Buck) writes:

>>donorgan@ix.netcom.com (Don Organ) writes:

>>>    3) Allowing static virtual data (and possibly nonstatic virtual
>>>        data). I haven't investigated what changes to the draft
>>>        this would require.

>>You haven't investigated what 1) and 2) would require.  You can't just
>>take out restrictions; you need to completely fill in all consequences
>>of your changes, so that the resulting language will be well-defined.

>Please don't dismiss static virtual data out of hand.  It already
>exists: The addresses of the virtual member functions of a class
>are static (per-class rather than per-instance) and virtual (deter-
>mined in the basis of the type of an object, rather than the type
>of the pointer), and they are data.

>For those compilers which implement virtual functions by means of a
>vtable, it is trivial to allow the vtable to contain data other than
>the addresses of the member functions of the class.

>-- George Mitchell (george@mvp.com)

It would not be as trivial as it seems because there are cases of multiple
v_tables for the same class, in some implementations.  This is especially in
segmented architectures but I can also imagine it in a lazy compiler, or a
compiler doing the template shuffle.

Also since static data is allowed it would be trivial to implement static
virtual data, simply have an function that returns the data wanted.  This also
makes it much easier if one of the base classes is redesigned, to use different
static data.

On another thought in this same thread ...

The only use a static virtual function would have is if it could be called
inside constructurs of a base class, or if their addresses could be taken
dynamically and they could be assigned to regular function pointers.

1) The questions in my mind go how would you implement them?
2) What would be the benefit?
3) How would you specify their linkage?

To implement them so that they will work in constructors requires that they set
up the virtual function table before the object is constructed.  That doesn't
look to hard to me, and which function is called in a regular virtual context
is well defined so it should not be too difficult.

A disadvantage of that approach is that it requires classes that have no normal
virtual members functions to have the overhead of virtual functions, but not
having a this pointer simplifies things a lot.

Implementing pointers to these functions would be interesting.  As they are
virtual functions the _must_ have an object to resolve their virtualness by
the current definition of virtual functions.  This implementation stresses
their virtualness much more then their stacness.

Another possible implementation would be to implement them equivalently to
an array of static member functions indexed by:
[typeid(object)]
Releasing them from the virtual function table and stress their staticness.
This is a much more useful definition. (In my opinion)  It adds to the langauge
to implement typeid and other functions like that, at no extra overhead.

This would lead to some suprises though, because if you don't define any _real_
virtual functions these definitions would be equivalent to regular static
definitions.

Also it would be make more sense to make function pointers to these functions
regular function pointers with some method of specifying their linkage.  This
may have some real advantages in the persistence problem.  As these functions
don't need an object but simply a source of typeinformation.

The problem is that seems to introduce another unituitive feature to the
language and another pitfall.















Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/07/05
Raw View
Ulf Schuenemann (schuenem@informatik.tu-muenchen.de) wrote:
: Before the introduction of RTTI "virtual static const char*className();"
: was the best example. Now the is the danger that type_info is missused
: to achieve something similar to virtual static.
: (I can remember suggestions in this newsgroup that wanted to extend
: type_info to contain several other infos about the class. As this
: info is not in type_info, there is the danger, that type_info is
: missused):

:  size_t dyn_sizeof (myObj*o)
:  { type_info ti = typeof(o)
:   if(ti == typeof(myObj))
:    return sizeof(myObj);
:   else if(ti == typeof(myDerived1))
:    return sizeof(myDerived1);
:   else ...
:  }

: I'll think we can agree that this is BAD style.

What you need is DirectToSOM C++, since it has an object model that
includes C++ classes (or, at least, the subset of C++ classes that you
specify to be SOM classes via DirectToSOM) as first-class objects at runtime.

    size_t dynamic_sizeof ( SOMObject & o )
    {
 return o.somGetClass()->somGetInstanceSize() ;
    }

You can pass this a reference to any SOM class instance object (or even any
SOM class object!) because all SOM classes are derived from SOMObject
either directly or indirectly.

Interestingly, some of the other uses put forward in this thread for static
virtual can also be solved by similar metaclass programming.

As always, my recommendation is the same : the C++ compilers to do what you
want exist right now.  If you vote with your wallets, the standards will
follow.





Author: jbuck@synopsys.com (Joe Buck)
Date: 1995/07/01
Raw View
donorgan@ix.netcom.com (Don Organ) writes:
>I'm preparing to submit a formal, "Public Comment" requesting that the
>prohibition against static virtual member functions be dropped.

Sigh.  To do so you'll have to define what a static virtual member
function is supposed to do, rigorously.  Removing the prohibition
against static virtual functions won't do.  How would you determine
how to resolve calls to static virtual function calls at runtime?
You can't use the object they are called on as there is no object.

>    2) Allowing the most derived static virtual member function to
>        be callable from its base classes' constructors.

First educate yourself about why the language works as it does.

class Base {
private:
 int data;
public:
 virtual int foo() { return 0;}
 Base() { data = foo();}
};

class Derived {
private:
 char * text;
public:
 virtual int foo() { return atoi(text);}
 Derived(char* arg) : text(arg) {}
};

Under your proposal, what happens when I construct a Derived object?
Answer: who knows?  You want Base::Base to call Derived::foo in that
case, but Derived::foo accesses a member that has not been initialized
(since the Base constructor is called first).  Forget it.  You'll have
to completely redesign the language to make your proposal work.  It's
unsafe to call a derived virtual function from a base constructor, because
it may refer to members of the derived object, members that have not yet
been constructed and are therefore in a random state.

Currently, an object starts out as raw memory, then becomes a Base,
and then becomes a Derived.  While the Base constructor is being called,
it's still a Base, not a Derived.  That's why Base::foo is called.

>    3) Allowing static virtual data (and possibly nonstatic virtual
>        data). I haven't investigated what changes to the draft
>        this would require.

You haven't investigated what 1) and 2) would require.  You can't just
take out restrictions; you need to completely fill in all consequences
of your changes, so that the resulting language will be well-defined.

>    - the opinion (something like strongly/weakly support/oppose or
>        "why bother?") - for #1-#3.

Forget it.  To be blunt, you don't seem competent to propose a language
change.  Please don't waste the committee's time.

Even if your proposals had merit, it's really too late at this stage.
What's needed at this point is a standard.  Proposals should only be
made to fix major defects or holes.
--
-- Joe Buck  <jbuck@synopsys.com> (not speaking for Synopsys, Inc)
Phone: +1 415 694 1729





Author: jim.fleming@bytes.com (Jim Fleming)
Date: 1995/07/02
Raw View
In article <ojxfFD200gjOB711db@andrew.cmu.edu>, rr2b+@andrew.cmu.edu says...
>
>donorgan@ix.netcom.com (Don Organ) writes:
>>I'm preparing to submit a formal, "Public Comment" requesting that the
>>prohibition against static virtual member functions be dropped.
>
[snip]
>...
>Excerpts from netnews.comp.std.c++: 1-Jul-95 Re: static virtual: Public
>.. Joe Buck@synopsys.com (2575)
>

You better do it soon because, as noted in the *August 1995* issue of
Dr. Dobb's Journal...

The public comment period ends July 25, 1995 and because of an upcoming
committee meeting the comments have to be in by July 6, 1995.

Evidently the comments can be submitted via e-mail but are not "official"
unless they are submitted on paper to ANSI.

Even though this public comment period appears to be short, I am sure that
some people could claim that you have had since 1989-1990 when the ANSI
standards work was started to comment.

Since most people do not have companies or universities that will pay
them to fly around the world and attend meetings for 5 years, you have
to use the official channels if you intend to participate without
incurring an enormous expense. Unfortunately, as you can see the official
channels give you very little time to respond and your inputs can be
easily "processed" by a nameless/faceless committee.

It would have been nice if the Usenet forum had been used to allow
a larger number of people to participate in the ISO/ANSI C++ standard.
This forum allows every poster to have an equal voice (or near equal,
when cancelbots are not deleting postings). People that need an unequal
advantage and who need to use traditional systems to promote their
agendas can not tolerate that type of equality. Hence, this forum becomes
void of discussions between the people working the standards issues on
a daily basis and those discussions are moved to more traditional (and
private) forums like voice, e-mail, and paper mail.

BTW, in the same issue of Dr. Dobb's Journal there is an article that
describes the proposals that are being made to revise the ISO/ANSI C
standard. You might have a better chance of getting your comments into
that process.

It looks like many of the people on the ANSI C and ANSI C++ committees
are the same. If (or when) the two languages converge, it is likely that
those people that are common to both efforts will have the most influence.
You might want to look into the ANSI C work also to make sure that you
are part of the "inside activity" of that process.

Jim Fleming
U.S. Citizen






Author: Robert Andrew Ryan <rr2b+@andrew.cmu.edu>
Date: 1995/07/02
Raw View
donorgan@ix.netcom.com (Don Organ) writes:
>I'm preparing to submit a formal, "Public Comment" requesting that the
>prohibition against static virtual member functions be dropped.

Excerpts from netnews.comp.std.c++: 1-Jul-95 Re: static virtual: Public
.. Joe Buck@synopsys.com (2575)

 (Point 2 from Don Organ's post)
> >    2) Allowing the most derived static virtual member function to
> >        be callable from its base classes' constructors.

> First educate yourself about why the language works as it does.
...
Excerpts from netnews.comp.std.c++: 1-Jul-95 Re: static virtual: Public
.. Joe Buck@synopsys.com (2575)

> class Derived {
> private:
>  char * text;
> public:
>  virtual int foo() { return atoi(text);}
>  Derived(char* arg) : text(arg) {}
> };

> Under your proposal, what happens when I construct a Derived object?
> Answer: who knows?  You want Base::Base to call Derived::foo in that
> case, but Derived::foo accesses a member that has not been initialized
(since the Base constructor is called first).

But in Joe Buck's example foo is NOT a static virtual member.  A static
virtual member couldn't access any derived members without violating the
type system since it has no object.  (and thus no Derived * without a
cast.)

One use of a static virtual member in this context might be:

class Base {
public:
    static virtual void foo(Base *);
    Base();
    int variesInDerivation;
}

class Derived : public Base {
public:
    static void foo(Base *);
}

Base::Base() {
    foo(this);
}

void Derived::foo(Base *b) {
 b->variesInDerivation=42;
}

But could this example be covered by a constructor for Base?

Base::Base(int varies)  {
    variesInDerivation=varies;
}

Derived::Derived() : Base(42) {
}

I think that would work.  It would be more typing though.  (Including
the Base(...) calls in all derived constructors, splitting the work of
the Base constructor up among a number of functions to reduce
duplication, etc...)

-Rob Ryan
Andrew Consortium (speaking only for myself here)









Author: wil@ittpub.nl (Wil Evers)
Date: 1995/07/03
Raw View
In article <3t2cl4$2mg@hermes.synopsys.com> jbuck@synopsys.com (Joe Buck)
writes:

> donorgan@ix.netcom.com (Don Organ) writes:
> >I'm preparing to submit a formal, "Public Comment" requesting that the
> >prohibition against static virtual member functions be dropped.

[snip]

> How would you determine
> how to resolve calls to static virtual function calls at runtime?
> You can't use the object they are called on as there is no object.

Don's proposal makes sense because there may or may not be an object. When
a static virtual member function is called through an object, the call can
be resolved just like a call to an ordinary virtual member function is
resolved, the difference being that the this pointer is not passed. As far
as I can see, the experts in this newsgroup seem to agree that there is no
*technical* reason for disallowing static virtual member functions.

> >    2) Allowing the most derived static virtual member function to
> >        be callable from its base classes' constructors.
>
> First educate yourself about why the language works as it does.
>
> class Base {
> private:
>  int data;
> public:
>  virtual int foo() { return 0;}
>  Base() { data = foo();}
> };
>
> class Derived {
> private:
>  char * text;
> public:
>  virtual int foo() { return atoi(text);}
>  Derived(char* arg) : text(arg) {}
> };
>
> Under your proposal, what happens when I construct a Derived object?
> Answer: who knows?  You want Base::Base to call Derived::foo in that
> case, but Derived::foo accesses a member that has not been initialized
> (since the Base constructor is called first).

[snip]

If foo() was defined as a static virtual member function, the compiler
would have flagged Derived::foo() as illegal. A static member function
doesn't have a this pointer, so it can't directly access any part of the
object being constructed, including uninitialized members in the derived
part of the object.
Again, Don's proposal makes sense. I don't like it, though, because it
would be an exception to the way non-static virtual member function calls
are resolved and because I think it's hard to implement.

[snip]

> To be blunt, you don't seem competent to propose a language
> change.  Please don't waste the committee's time.

Blunt indeed. If you're opposed to static virtual class members, you
should simply say why. I think Don deserves credit for the courage it
takes to submit such a proposal. I also think he deserves credit for
asking for help in this newsgroup.

> Even if your proposals had merit, it's really too late at this stage.
> What's needed at this point is a standard.  Proposals should only be
> made to fix major defects or holes.

Even in this stage, it would be a shame if the committee would miss an
opportunity to simultaneously simplify the language and increase its
expressive power.

- Wil





Author: wstfld@ibm.net (Chris Wuestefeld)
Date: 1995/07/03
Raw View
jbuck@synopsys.com (Joe Buck) wrote:
>[...]
>Under your proposal, what happens when I construct a Derived object?
>Answer: who knows?  You want Base::Base to call Derived::foo in that
>case, but Derived::foo accesses a member that has not been initialized
>(since the Base constructor is called first).  Forget it.
When was the last time that you wrote a static function that accesses
an instance's data?  You never did, since you can't (no this pointer).
I don't think that anyone is proposing that these functions receive a
this pointer, only that they be referencable from an instance via its
vtable.  Thus, this is not an issue.

>Forget it.  To be blunt, you don't seem competent to propose a language
>change.  Please don't waste the committee's time.
Foot in mouth?

Still, proposal (2) is still, in my mind, a bad idea.  This is simply
because of the current behavior of 'normal' virtual functions in
constructors (see ARM, sec 10.9c).  Allowing an exception for static
virtual functions might be technically feasible, but probably cause
more confusion than it's worth.

I am very much in favor of (1), that is, allowing static virtual
functions.  In conversations with coworkers, the only argument has
been, "How can that work? They don't have a this pointer?"  I think
that in the posts here, that's been shown to not be a problem.
Moreover, argument based on the implementation artifact of vtables
isn't valid.  The job of the committee (I think) should be to decide
if the concept has merit, and if so, is it worth doing -- not simply
saying that it's not resonant with current implementation.

Chris Wuestefeld
wstfld@ibm.net

HAVE *YOU* EXPORTED A CRYPTO SYSTEM TODAY? --> http://dcs.ex.ac.uk/~aba/x.html
--rsa--------------------------------8<-------------------------------------
#!/usr/local/bin/perl -s-- -export-a-crypto-system-sig -RSA-in-3-lines-PERL
($k,$n)=@ARGV;$m=unpack(H.$w,$m."\0"x$w),$_=`echo "16do$w 2+4Oi0$d*-^1[d2%
Sa2/d0<X+d*La1=z\U$n%0]SX$k"[$m*]\EszlXx++p|dc`,s/^.|\W//g,print pack('H*'
,$_)while read(STDIN,$m,($w=2*$d-1+length($n||die"$0 [-d] k n\n")&~1)/2)
-------------------------------------8<-------------------------------------
TRY: echo squeamish ossifrage | rsa -e 3 7537d365 | rsa -d 4e243e33 7537d365






Author: donorgan@ix.netcom.com (Don Organ)
Date: 1995/06/29
Raw View
I'm preparing to submit a formal, "Public Comment" requesting that the
prohibition against static virtual member functions be dropped.
I'm requesting that anyone who supports or opposes this request send me
e-mail (see below), so that I can include this survey in my comment.
This may help the committee judge the extent of support this has
(or lacks) - making this a more credible comment.

Recent postings on this topic covered three related, but separate
concepts:
    1) Removal of the prohibition of static virtual member functions.
        The change to the draft would be in section 9.5.1, paragraph 2
        [class.static.mfct]. The sentence "A static member function
        shall not be virtual." would be dropped, leaving the ammended
        paragraph:
        "[Note: a static member function does not have a this pointer
        (9.4.2). ] There shall not be a static and a nonstatic
        member function with the same name and the same parameter types
        (13.1). A static member function shall not be declared const,
        volatile or const volatile."

    2) Allowing the most derived static virtual member function to
        be callable from its base classes' constructors. This would
        require changes to section 12.7 paragraph 3 [class.cdtor].
        The second sentence should be modified to "When a *nonstatic*
        virtual function is called ... from a constructor ... the
        function called is the one defined in the constructor's ...
        own class or overriding it in one of the other base classes
        of the complete object." - the change is the addition
        of the word nonstatic.

    3) Allowing static virtual data (and possibly nonstatic virtual
        data). I haven't investigated what changes to the draft
        this would require.

(Personally, I'm in strongly in favor of #1, sympathetic toward #2 and
opposed to #3 since I don't understand the need and believe it would
distract from #1. But I feel it is appropriate to consolodate the
comments from all - since they are related. I'll suggest that #1 could
be accepted without #2 or #3 and that #2 and #3 can be considered
independently.)

Regarding e-mail. If you have an opinion one way or the other, please
send me:
    - the opinion (something like strongly/weakly support/oppose or
        "why bother?") - for #1-#3.
    - your country (may be significant to ANSI)
    - (optional) short comments related to D&E section 6.4.1 (Criteria)
        such as
        precision - are the changes I've identified for #1 and #2
            correct and sufficient? What changes for #3?
        rationale - why needed? who is audience? what kind of
            programming/design styles would this support? other
            languages with this feature?
        compatibility with existing code? (I believe #1 would no
            impact, I need help with #2 and #3).
        what are the good arguments for not making these changes

I'll post a summary somewhere around July 9th.
Note: Since the next committee meeting starts on July 9th, I need to
ensure they receive this comment by July 5th. This leaves not much time
(especially considering many here in the states will be celebrating
a 4-day weekend for July 4th). I apologize for the short notice.
Also note: I'm requesting e-mail rather then postings to avoid
cluttering comp.std.c++. I'll also monitor comp.std.c++ in case anyone
prefers to comment publicly.


Thanks for your consideration.

Don Organ
donorgan@ix.netcom.com







Author: schuenem@informatik.tu-muenchen.de (Ulf Schuenemann)
Date: 1995/06/29
Raw View
+++++
+BTW: An Error in 9.4.1,1 (IMO *nonstatic* should be added):
+     "... A nonstatic member function may also be called
+     directly using the function call syntax (...):
+     - from within the body of a *nonstatic* member function ..."
+++++

In article <3stcjt$72c@ixnews6.ix.netcom.com>, donorgan@ix.netcom.com (Don Organ) writes:
|> I'm preparing to submit a formal, "Public Comment" requesting that the
|> prohibition against static virtual member functions be dropped.

Thanx that you volunteer. Now we're getting concrete. Some remarks to #1:

10.3,7: Drop the second sentence "Nor can a virtual function be a static
member, since ..." , leaving:
"[Note: the virtual specifier implies membership, so a virtual function
cannot be a nonmember (7.1.2) function. A virtual function declared in
one class can be declared a friend in another class.]"

To allow dynamic binding of static virtual memfcts (svmf) used in
functioncall-syntax:
9.4.1,2: must be changed, so that a name that resolves to a static
(virtual) memfct is NOT "transformed into a qualified-id (5.1) in which the
nested-name-specifier" names the" (static) "class of the member function."
but a "class member access expression (5.2.4) using (*this) ...".
But don't ask me how to work this into the paragraph using such a formal
English correctly.

Memberfunctionpointers:
- A point that we didn't discuss yet. To keep it simple, IMHO we should
leave them being of function type and not member function type.
(See 9.2,10 etc).

---
|> (Personally, I'm in strongly in favor of #1, sympathetic toward #2 and
|> opposed to #3 since I don't understand the need and believe it would
|> distract from #1.

I agree wholeheartedly (#1:strong support, #2:sympathetic, #3:opposed).
Although, as George Mitchell noted, #3 could technically be seen like
the vtable but with objects of other type besides pointer-to-function,
I can't oversee the semantic impact of virtual static data and the
changes needed in the standard. That's why the committee will refuse #3.
We should wait and promote #3 for the revision of the (will-be) standard.

|>         precision - are the changes I've identified for #1 and #2
|>             correct and sufficient? What changes for #3?
They are correct.
AFAIS the (your + my) changes are sufficient to allow the definition
of svmf. But I can't oversee if they are sufficient to allow
dynamic binding of svmf used in functioncall- and '.'-syntax.


Ulf Schuenemann

PS: My country is Germany.
--------------------------------------------------------------------
Ulf Sch   nemann
Fakult   t f   r Informatik, Technische Universit   t M   nchen, Germany.
email: schuenem@informatik.tu-muenchen.de
WWW:   http://www.informatik.tu-muenchen.de/cgi-bin/nph-gateway/hphalle2/~schuenem/index.html
main(){char*a;printf(a="main(){char*a;printf(a=%c%s%c,34,a,34);}",34,a,34);}