Topic: Responses to ~const 1.6: Possible generalizations of ~const


Author: jbuck@galileo.berkeley.edu (Joe Buck)
Date: 4 Mar 91 05:06:53 GMT
Raw View
In article <4198@lupine.NCD.COM>, rfg@NCD.COM (Ron Guilmette) writes:
|> In article <NGO.91Feb19114034@tammy.harvard.edu> ngo@tammy.harvard.edu (Tom Ngo) writes:
|> +
|> +Background information to this posting was in a very recent summary.
|> +
|> ...
|> +    ~volatile   Do allow optimization on this object [even if the
|> +                enclosing object is declared volatile].
|> +
|> +Joe Buck <jbuck@galileo.berkeley.edu> was against ~volatile on the
|> +grounds that it would add virtually nothing to the language; it would
|> +"give a tiny bit of useful information to an optimizing compiler,
|> +[but] it would gain nothing in expressive capability."
|> +
|> +Joe Buck and Ron Guilmette <rfg@ncd.com> felt that symmetry and
|> +simplicity of implementation might be good reasons to permit a
|> +~volatile specifier.

Tom makes it look like I contradict myself.  No, I meant that ~volatile
doesn't get you much extra but you may as well throw it in to maintain
a uniform grammar, since volatile may appear anywhere that const can
at present.

|> One could argue that ~volatile has very little usefulness, however the
|> same could be said for `volatile' itself.  Does that mean that we should
|> get rid of `volatile'?  I think not.

There are places that volatile is needed, especially when interacting
with hardware, signals, and interrupt service routines.  The "pre-volatile"
trick was putting in a comment saying "WARNING: don't use -O on this code".

--
Joe Buck
jbuck@galileo.berkeley.edu  {uunet,ucbvax}!galileo.berkeley.edu!jbuck




Author: schwartz@groucho.cs.psu.edu (Scott Schwartz)
Date: 20 Feb 91 02:39:34 GMT
Raw View
ngo@tammy.harvard.edu (Tom Ngo) writes:
  I am still interested in hearing about potential uses for ~virtual.

As long as we are improving the language...

Make the default be that all member functions are virtual (like they
would be in an object oriented language).  Then when someone wants C
style behaviour they can tag individual functions as not virtual.
Like "register" this may be considered a hint to an optimizing
compiler, which will be looking to do such things on its own anyway.




Author: ngo@tammy.harvard.edu (Tom Ngo)
Date: 19 Feb 91 16:40:34 GMT
Raw View
Background information to this posting was in a very recent summary.

Having a ~const specifier suggests four other specifiers:

    ~volatile
    ~register
    ~inline
    ~virtual

Jim Adcock <jimad@microsoft.UUCP> suggested the last three and gave
the following proposed definitions for all four:

    ~volatile   Do allow optimization on this object [even if the
                enclosing object is declared volatile].

    ~register   Do not enregister this object, even when optimizing.

    ~inline     Do make this method a real function call.

    ~virtual    Do not put this method in the vtable [even if a
                function of exactly the same type was declared virtual
                in a base class].

Joe Buck <jbuck@galileo.berkeley.edu> was against ~volatile on the
grounds that it would add virtually nothing to the language; it would
"give a tiny bit of useful information to an optimizing compiler,
[but] it would gain nothing in expressive capability."

Joe Buck and Ron Guilmette <rfg@ncd.com> felt that symmetry and
simplicity of implementation might be good reasons to permit a
~volatile specifier.

Jim Adcock seemed to feel the most strongly about ~inline, which would
give an simple way to debug inline functions without having to disable
inlining for a whole program.  The mention of ~inline sparked a
separate debate about compiler hints which I will not summarize.

Before I give my reactions, let me say that these specifiers will
probably get only a mention in my proposal to the ANSI committee.  I
think they are sufficiently different from ~const that they should be
treated separately, and I have no plans to write up proposals for
them.  (Any takers?)  Having said that,

   * I agree that ~volatile would be just about useless, but that for
     the sake of symmetry and simplicity it might be worth throwing in.

   * The existing keywords "inline" and "register" interact little
     with other specifications.  In particular, they affect neither
     the behavior of a program nor the validity of the rest of the
     code.  This is by necessity, because according to the ARM they
     are only hints: the programmer cannot know before compile time
     whether the hints will actually be taken.

   * The proposed phrases ~inline and ~register should mean exactly
     the opposite of inline and register, except that ~inline should
     not be a mere hint.  It would be used primarily to permit
     source-level debugging of a particular function without having to
     recompile a whole program without inlining.  If you write
     ~inline, you will want to be certain that your function will
     actually be implemented as a function call!

   * ~virtual is the one I am least convinced about.  Clearly it does
     nothing to a method which is not already in the vtable of any
     base class.  So we are left with the following semantics.
     Following ARM 10.2,

         If a class "base" contains a virtual function vf(), and a
         class "derived" derived from it also contains a function vf
         of the same type, then a call of vf for an object of class
         "derived" invokes derived::vf() (even if the access is
         through a pointer or reference to "base").  The derived class
         function is said to override the base class function....

         ...the interpretation of the call of a virtual function
         depends on the type of the object for which it is called,
         whereas the interpretation of a call of a nonvirtual member
         function depends only on the type of the pointer or reference
         denoting that object....

         ...An overriding function is itself considered virtual UNLESS
         it is declared ~virtual.

     I am uncomfortable with the fact that someone writing a function
     that takes pointers to "base" cannot know whether calls to vf()
     are really virtual for all derived classes, without looking at
     all of their declarations.

     I am still interested in hearing about potential uses for ~virtual.

--
  Tom Ngo
  ngo@harvard.harvard.edu
  617/495-1768 lab number, leave message




Author: schwartz@groucho.cs.psu.edu (Scott Schwartz)
Date: 20 Feb 91 02:31:57 GMT
Raw View
ngo@tammy.harvard.edu (Tom Ngo) writes:
   ~const ~volatile ~register ~inline ~virtual

Don't forget ~alias!

:-)/2




Author: jimad@microsoft.UUCP (Jim ADCOCK)
Date: 25 Feb 91 20:23:31 GMT
Raw View
Regards ~virtual:

Also note, under today's system, where a derived class cannot explicitly
declare a method ~virtual, the possibility exists for a base class
programmer to "hijack" a private derived class method by declaring
it public virtual in the base class.  For example, when modifying
a base class, the base class programmer might accidentally choose a virtual
function name used privately non-virtually in a derived class.
The effect would be that what was intended to be a private non-virtual
method in the derived class is accidentally promoted, without warning,
to become one flavor of a public virtual method of the base class.

If the derived class programmer could explicitly mark private non-virtual
methods with ~virtual, then attempts to make such virtual in the base
class would cause an error.  I claim this is how it should be.  Base
classes should be able to protect and defend methods declared in the
base class.  Derived classes should be able to protect and defend methods
declared in the derived class.  If the two classes refuse to agree,
a compile-time error should result.




Author: jimad@microsoft.UUCP (Jim ADCOCK)
Date: 25 Feb 91 20:06:41 GMT
Raw View
In article <NGO.91Feb19114034@tammy.harvard.edu> ngo@tammy.harvard.edu (Tom Ngo) writes:
|   * ~virtual is the one I am least convinced about.  Clearly it does
|     nothing to a method which is not already in the vtable of any
|     base class.  So we are left with the following semantics.
|     Following ARM 10.2,
|
|         If a class "base" contains a virtual function vf(), and a
|         class "derived" derived from it also contains a function vf
|         of the same type, then a call of vf for an object of class
|         "derived" invokes derived::vf() (even if the access is
|         through a pointer or reference to "base").  The derived class
|         function is said to override the base class function....
|
|         ...the interpretation of the call of a virtual function
|         depends on the type of the object for which it is called,
|         whereas the interpretation of a call of a nonvirtual member
|         function depends only on the type of the pointer or reference
|         denoting that object....
|
|         ...An overriding function is itself considered virtual UNLESS
|         it is declared ~virtual.
|
|     I am uncomfortable with the fact that someone writing a function
|     that takes pointers to "base" cannot know whether calls to vf()
|     are really virtual for all derived classes, without looking at
|     all of their declarations.
|
|     I am still interested in hearing about potential uses for ~virtual.

An alternative interpretation of ~virtual that might make sense is
that a ~virtual in a derived class that conflicts with a virtual in
a public? base class is an error.  In my experience, more compulsive C++
programmers desire to explicitly state whether a function in a derived
class is virtual or not -- they desire this for "documentary" purposes.  Today,
they do this something like:

#define non_virtual /* nothing */

then mark all their routines either virtual or non-virtual:

class derived : public base
{
....
public:
 non_virtual int   doX();
 virtual     void  doY();
 non_virtual void  doZ();
....
};

The problem with this approach is that it requires the class deriver
to correctly mark whether a particular function is indeed virtual or
not -- a function incorrectly marked non-virtual will not be diagnosed.

If ~virtual were explicitly included in the language, then compilers
could diagnose those situations where assuptions about non-virtualness
are stated incorrectly in derived classes.  Today, such a check simply
cannot exist.




Author: rfg@NCD.COM (Ron Guilmette)
Date: 2 Mar 91 21:21:52 GMT
Raw View
In article <NGO.91Feb19114034@tammy.harvard.edu> ngo@tammy.harvard.edu (Tom Ngo) writes:
+
+Background information to this posting was in a very recent summary.
+
...
+    ~volatile   Do allow optimization on this object [even if the
+                enclosing object is declared volatile].
+
+Joe Buck <jbuck@galileo.berkeley.edu> was against ~volatile on the
+grounds that it would add virtually nothing to the language; it would
+"give a tiny bit of useful information to an optimizing compiler,
+[but] it would gain nothing in expressive capability."
+
+Joe Buck and Ron Guilmette <rfg@ncd.com> felt that symmetry and
+simplicity of implementation might be good reasons to permit a
+~volatile specifier.

One could argue that ~volatile has very little usefulness, however the
same could be said for `volatile' itself.  Does that mean that we should
get rid of `volatile'?  I think not.

Regarding the `symmetry' argument in favor of making ~const and ~volatile
into one unified proposal, it is my opinion that it would actually be
*easier* for implementors to implement both of them than it would be
for implementors to implement either one of them alone.  That's because
of the tight relationship between const and volatile (within a compiler).

--

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// New motto:  If it ain't broke, try using a bigger hammer.