Proposal: interfaces

98 views
Skip to first unread message

christopher diggins

unread,
Apr 9, 2004, 10:45:03 AM4/9/04
to
Motivation
==========
C++ designs that inherit from multiple pure abstract base classes introduce
multiple vtables that cause rapid bloating of objects that is uneccessary.
The current solution is an unacceptable "just don't do that".

Proposed Solution
=================
- interface reference type (fat pointer which points to object and to
interface function table)
- implements interface declarations

class FuBar {
implement IFuBar;
...
};

- instantiable interface declaration semantics i.e.

interface SomeInterface {
FuBar1();
...
};

- a downloadable example and demonstration is available at :
http://www.heron-language.com/heronfront.html

Advantages of Proposal
======================
- no code bloat when compared to comparable ABC design
- faster than comparable designs using ABC's
- introduction of proposal requires virtually no changes to other parts of
language standard

--
Christopher Diggins
http://www.cdiggins.com
http://www.heron-language.com

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Larry Evans

unread,
Apr 9, 2004, 11:49:19 AM4/9/04
to
christopher diggins wrote:
> Motivation
> ==========
> C++ designs that inherit from multiple pure abstract base classes introduce
> multiple vtables that cause rapid bloating of objects that is uneccessary.
> The current solution is an unacceptable "just don't do that".
>
> Proposed Solution
> =================
> - interface reference type (fat pointer which points to object and to
> interface function table)
> - implements interface declarations
Hi christopher,

I'm just guessing, but also hoping that what you're proposing might
help in something akin to dynamic inheritance. I've wanted to
create something like a "base" class heirarchy and then "decorate" it
with different "views". An example of what I'm trying to do is at:

http://groups.yahoo.com/group/boost/files/regexp_first.zip

it implements inheritance of T via superclass smart_ptr<T>; however,
this obviously requires the inheriting class to forward all calls to the
superclass. But the inheriting class would need to have a virtual
function table whose only purpose would be to provide forwarding functions.

Can you tell me how this interface feature would help in the
regexp_first code?

I'd be happy to email you the code directly if that would help.

Regards,
Larry

Larry Evans

unread,
Apr 9, 2004, 6:38:21 PM4/9/04
to
Larry Evans wrote:
> christopher diggins wrote:
[snip]

> with different "views". An example of what I'm trying to do is at:
>
> http://groups.yahoo.com/group/boost/files/regexp_first.zip
>
Another example of where interfaces MAY be useful is with the code at:

http://groups.yahoo.com/group/boost/files/managed_ptr/overhead_referent_vals.zip

The Overhead will contain a virtual DTOR in order to be able to call the
Referent DTOR, but this causes the "bloat" of another VFT. Could this
interface feature avoid that?

Alberto Barbati

unread,
Apr 10, 2004, 2:50:20 AM4/10/04
to
christopher diggins wrote:
> Motivation
> ==========
> C++ designs that inherit from multiple pure abstract base classes introduce
> multiple vtables that cause rapid bloating of objects that is uneccessary.
> The current solution is an unacceptable "just don't do that".

This motivation is valid in several problem domains, yet it's not valid
in general. I still can imagine examples where abstract base classes are
necessary and where the overhead of current implementation is
acceptable. Whether your motivation is sufficient to justify a language
extension, I cannot tell. Keep in mind that linkers are getting smarter
and smarter and link-time code generation may (if not now, in the
future) greatly reduce the code bloat that you are worried about.

> Proposed Solution
> =================
> - interface reference type (fat pointer which points to object and to
> interface function table)
> - implements interface declarations
>
> class FuBar {
> implement IFuBar;
> ...
> };
>
> - instantiable interface declaration semantics i.e.
>
> interface SomeInterface {
> FuBar1();
> ...
> };

You suggest to introduce two new keywords but for sure you know how the
committee is reluctant to add those. The "implement" keyword is
unnecessary, IMHO. I don't see any problem in using the common syntax:

class FuBar : public IFuBar
...
};

As for the "interface" keyword, a replacement could be:

class SomeInterface = 0 {
FuBar1();
...
};

as "= 0" is already used for abstract virtual functions, the meaning
should be clear. Alternatively, one could overload the keyword "virtual":

virtual class SomeInterface {
FuBar1();
...
};

> - a downloadable example and demonstration is available at :
> http://www.heron-language.com/heronfront.html

The fact that you can provide one implementation that gives good results
doesn't demonstrate anything. See below...

> Advantages of Proposal
> ======================
> - no code bloat when compared to comparable ABC design
> - faster than comparable designs using ABC's
> - introduction of proposal requires virtually no changes to other parts of
> language standard
>

Your "solution" looks just like a syntax to me. It's not self-evident
how the advantages that you are claiming are obtained and, even more
important, why similar advantages cannot be obtained in another way.

Exactly I would like to understand:

1) precisely what code won't be generated w.r.t. the ABC syntax

2) how your proposed syntax helps to eliminate such code

3) why your proposed syntax is essential to eliminate such code (i.e.:
does it provide an essential information about the code that couldn't be
obtained in other way programmatically, possibly at link-time?)

--
Alberto Barbati

Dave Harris

unread,
Apr 10, 2004, 12:10:32 PM4/10/04
to
cdig...@videotron.ca ("christopher diggins") wrote (abridged):

> - instantiable interface declaration semantics i.e.

How does an interface differ from an abstract base class? Can an interface
have non-pure virtual functions? Non-virtual functions? Static member
variables? Or are they just like in Java?

Your motive seems to be performance. I suspect the Java model is more
restrictive than is necessary for performance, for ideological reasons. I
think that the killer problem with implementing ABCs is dealing with
non-static instance variables.

But I could be wrong. I would like to see a much more detailed analysis
than that you show on your web site. I'd like to see exactly where the
overhead of ABCs comes from. Have you considered other implementation
techniques for ABCs, eg thunks, or cached searches? Can you prove that the
only way to get performance is by using the restricted form of interfaces?

-- Dave Harris, Nottingham, UK

John Nagle

unread,
Apr 10, 2004, 3:11:45 PM4/10/04
to
Could you arrange to host your files on an openly accessable
website? Thanks.

John Nagle
Animats

Larry Evans wrote:

> Larry Evans wrote:
>
>> christopher diggins wrote:
>
> [snip]
>
>> with different "views". An example of what I'm trying to do is at:
>>
>> http://groups.yahoo.com/group/boost/files/regexp_first.zip
>>
> Another example of where interfaces MAY be useful is with the code at:
>
> http://groups.yahoo.com/group/boost/files/managed_ptr/overhead_referent_vals.zip
>

---

christopher diggins

unread,
Apr 11, 2004, 1:16:47 AM4/11/04
to
"Dave Harris" <bran...@cix.co.uk> wrote in message
news:memo.20040410131032.2400A@brangdon.m...

> cdig...@videotron.ca ("christopher diggins") wrote (abridged):
> > - instantiable interface declaration semantics i.e.
>
> How does an interface differ from an abstract base class? Can an interface
> have non-pure virtual functions? Non-virtual functions? Static member
> variables? Or are they just like in Java?
>
> Your motive seems to be performance.

My motive is performance in so much that I want to have the freedom to write
a class that implements multiple interfaces without having to worry about
being hit with ever-increasing size and speed penalties that are
uneccessary.

>I suspect the Java model is more
> restrictive than is necessary for performance, for ideological reasons. I
> think that the killer problem with implementing ABCs is dealing with
> non-static instance variables.

I think the killer problem is the overwhelmingly common misconception that
an interface is the same as an ABC and that the functions should be virtual.

> But I could be wrong. I would like to see a much more detailed analysis
> than that you show on your web site. I'd like to see exactly where the
> overhead of ABCs comes from.

I would have thought that was relatively common knowledge.

> Have you considered other implementation
> techniques for ABCs, eg thunks, or cached searches?

No, I am not concerned with ABC's specifically but how they are a poor
substitute for an interface.

> Can you prove that the
> only way to get performance is by using the restricted form of interfaces?

I can't prove that because it isn't true. There are lots of ways improving
performance.

> -- Dave Harris, Nottingham, UK

--

---

David Abrahams

unread,
Apr 11, 2004, 7:03:45 PM4/11/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> "Dave Harris" <bran...@cix.co.uk> wrote in message
> news:memo.20040410131032.2400A@brangdon.m...
>> cdig...@videotron.ca ("christopher diggins") wrote (abridged):
>> > - instantiable interface declaration semantics i.e.
>>
>> How does an interface differ from an abstract base class? Can an interface
>> have non-pure virtual functions? Non-virtual functions? Static member
>> variables? Or are they just like in Java?
>>
>> Your motive seems to be performance.
>
> My motive is performance in so much that I want to have the freedom to write
> a class that implements multiple interfaces without having to worry about
> being hit with ever-increasing size and speed penalties that are
> uneccessary.
>
>>I suspect the Java model is more
>> restrictive than is necessary for performance, for ideological reasons. I
>> think that the killer problem with implementing ABCs is dealing with
>> non-static instance variables.
>
> I think the killer problem is the overwhelmingly common misconception that
> an interface is the same as an ABC and that the functions should be virtual.

Has anyone suggested the "good-old CRTP" yet?

// base class template for all interfaces
template <class Derived>
struct interface
{
protected:
Derived& self()
{ return *static_cast<Derived*>(this); }

Derived const& self() const
{ return *static_cast<Derived const*>(this); }
};

// a specific interface - requires that Derived supports foo and bar
template <class Derived>
struct foobar : interface<Derived>
{
void baz()
{
this->self().foo();
this->self().bar();
}
};

// A specific implementation of the foobar interface
struct my_foobar : foobar<my_foobar>
{
void foo();
void bar();
};

Look, ma, no virtual functions!

Cheers,
Dave

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

vze2...@verizon.net

unread,
Apr 12, 2004, 2:44:48 PM4/12/04
to
>
> Has anyone suggested the "good-old CRTP" yet?
>
> // base class template for all interfaces
> template <class Derived>
> struct interface
> {
> protected:
> Derived& self()
> { return *static_cast<Derived*>(this); }
>
> Derived const& self() const
> { return *static_cast<Derived const*>(this); }
> };
>
> // a specific interface - requires that Derived supports foo and bar
> template <class Derived>
> struct foobar : interface<Derived>
> {
> void baz()
> {
> this->self().foo();
> this->self().bar();
> }
> };
>
> // A specific implementation of the foobar interface
> struct my_foobar : foobar<my_foobar>
> {
> void foo();
> void bar();
> };
>
> Look, ma, no virtual functions!
>
> Cheers,
> Dave
>

Is't there a problem when using different classes implementing foobar?
I would have to declare my_foobar and your_foobar like this:

foobar< my_foobar > & foobar_1 = *new my_foobar;
foobar< your_foobar > & foobar_2 = *new your_foobar;

Then references foobar_1 and foobar_2 would have different types
which is not what happens for interfaces in Java, for example, which is
a limitation since I won't be able, for instance, to define a function i
that has a parameter of type "interface foobar" unless I want to
templatize everything that deals with that interface.

Regards,

--
Aleksandr Morgulis
aleksandr...@verizon.net

christopher diggins

unread,
Apr 12, 2004, 11:29:13 PM4/12/04
to
"David Abrahams" <da...@boost-consulting.com> wrote in message
news:ur7uuo...@boost-consulting.com...

> cdig...@videotron.ca ("christopher diggins") writes:
>

<snip>

> Has anyone suggested the "good-old CRTP" yet?

<snip>

> Look, ma, no virtual functions!

The CRTP(?) approach does indeed have no virtual functions but is lacking of
polymorphism on the interface because every "implementation" would have a
different base type.

---

christopher diggins

unread,
Apr 12, 2004, 11:33:05 PM4/12/04
to
"Alberto Barbati" <Alberto...@libero.it> wrote in message
news:HVGdc.118593$Kc3.3...@twister2.libero.it...

> christopher diggins wrote:
> > Motivation
> > ==========
> > C++ designs that inherit from multiple pure abstract base classes
introduce
> > multiple vtables that cause rapid bloating of objects that is
uneccessary.
> > The current solution is an unacceptable "just don't do that".
>
> This motivation is valid in several problem domains, yet it's not valid
> in general. I still can imagine examples where abstract base classes are
> necessary and where the overhead of current implementation is
> acceptable. Whether your motivation is sufficient to justify a language
> extension, I cannot tell. Keep in mind that linkers are getting smarter
> and smarter and link-time code generation may (if not now, in the
> future) greatly reduce the code bloat that you are worried about.

This was a big error on my part in the presentation of the proposal. I don't
propose to replace ABC's but rather introduce interfaces as being an
appropriate alternative for certain design scenarios which call for them
(i.e. behaves-like and looks-like object relationships). I agree that ABC's
are a perfectly acceptable and balanced solution in many cases and shouldn't
be replaced. Linkers do nothing to deal with the larger problem of object
bloat when implementing large numbers of ABC's.

> > Proposed Solution
> > =================
> > - interface reference type (fat pointer which points to object and to
> > interface function table)
> > - implements interface declarations
> >
> > class FuBar {
> > implement IFuBar;
> > ...
> > };
> >
> > - instantiable interface declaration semantics i.e.
> >
> > interface SomeInterface {
> > FuBar1();
> > ...
> > };
>
> You suggest to introduce two new keywords but for sure you know how the
> committee is reluctant to add those. The "implement" keyword is
> unnecessary, IMHO. I don't see any problem in using the common syntax:

The committee prejudices don't concern me at this point with regards to the
syntax. But in general, I have confidence that they measure each proposal
carefully and separately without preconcieved notions.

> class FuBar : public IFuBar
> ...
> };
>
> As for the "interface" keyword, a replacement could be:
>
> class SomeInterface = 0 {
> FuBar1();
> ...
> };
>
> as "= 0" is already used for abstract virtual functions, the meaning
> should be clear. Alternatively, one could overload the keyword "virtual":
>
> virtual class SomeInterface {
> FuBar1();
> ...
> };

Your syntax proposal is interesting and clever, I credit you with it in the
rewrite of my proposal.

> > - a downloadable example and demonstration is available at :
> > http://www.heron-language.com/heronfront.html
>
> The fact that you can provide one implementation that gives good results
> doesn't demonstrate anything. See below...

I am demonstrating the technique as opposed to proving things. Some people
need to see tangible work before they take theoretical notions into
consideration.

> > Advantages of Proposal
> > ======================
> > - no code bloat when compared to comparable ABC design
> > - faster than comparable designs using ABC's
> > - introduction of proposal requires virtually no changes to other parts
of
> > language standard
> >
>
> Your "solution" looks just like a syntax to me. It's not self-evident
> how the advantages that you are claiming are obtained and, even more
> important, why similar advantages cannot be obtained in another way.

It is more than syntax I am trying to propose. It is the fact that an
interface is not an ABC. See http://www.heron-language.com/abc-iop.html.

> Exactly I would like to understand:
>
> 1) precisely what code won't be generated w.r.t. the ABC syntax

Virtual functions and dynamic dispatch of functions within the object
implementing an interface would not be generated.

> 2) how your proposed syntax helps to eliminate such code

Becaue an interface is clearly not an ABC there is no point to using virtual
functions as it conflicts with the intent.

> 3) why your proposed syntax is essential to eliminate such code (i.e.:
> does it provide an essential information about the code that couldn't be
> obtained in other way programmatically, possibly at link-time?)

The proposed syntax differentiates the notion of implementing an interface
from inheriting an ABC. The main difference is that implementing an
interface does no imply virtualization of the functions. This fact can by
easily leveraged by an implementation to create a more efficient usage of
interfaces compared with the naive comparable implementation using ABC's.
The intent of using ABC as an interface is not easily knowable to a
compiler/linker and having the compiler have different representations of an
ABC depending on context would probably not be a practically possible
option.

Thanks for your comments Alberto

---

David Abrahams

unread,
Apr 12, 2004, 11:35:56 PM4/12/04
to
vze2...@verizon.net writes:

> Is't there a problem when using different classes implementing
> foobar?

It depends on your requirements. Please re-read the part of my post
that you snipped:

-----


cdig...@videotron.ca ("christopher diggins") wrote:
> My motive is performance in so much that I want to have the freedom to write
> a class that implements multiple interfaces without having to worry about
> being hit with ever-increasing size and speed penalties that are
> uneccessary.
>
>>I suspect the Java model is more
>> restrictive than is necessary for performance, for ideological reasons. I
>> think that the killer problem with implementing ABCs is dealing with
>> non-static instance variables.
>
> I think the killer problem is the overwhelmingly common misconception that
> an interface is the same as an ABC and that the functions should be virtual.

-------

> I would have to declare my_foobar and your_foobar like this:
>
> foobar< my_foobar > & foobar_1 = *new my_foobar;
> foobar< your_foobar > & foobar_2 = *new your_foobar;
>
> Then references foobar_1 and foobar_2 would have different types
> which is not what happens for interfaces in Java, for example, which is
> a limitation since I won't be able, for instance, to define a function i
> that has a parameter of type "interface foobar" unless I want to
> templatize everything that deals with that interface.

Of course. You can't have it both ways: either you get type erasure,
dynamic polymorphism, and you pay the runtime cost of virtual
functions, or you preserve type distinctions, use static
polymorphism, and avoid the runtime cost of virtual functions. In
C++, it's up to you to choose.

--
Dave Abrahams
Boost Consulting

http://www.boost-consulting.com

Pete Vidler

unread,
Apr 13, 2004, 10:58:46 AM4/13/04
to
christopher diggins wrote:
[snip]

> The CRTP(?) approach does indeed have no virtual functions but is lacking of
> polymorphism on the interface because every "implementation" would have a
> different base type.

CRTP = Curiously Recurring Template Pattern. The compile-time
polymorphism is gained through the use of templates whenever you need to
take different "interfaces".

-- Pete

David Abrahams

unread,
Apr 13, 2004, 10:59:12 AM4/13/04
to
da...@boost-consulting.com (David Abrahams) writes:

> Of course. You can't have it both ways: either you get type erasure,
> dynamic polymorphism, and you pay the runtime cost of virtual
> functions, or you preserve type distinctions, use static
> polymorphism, and avoid the runtime cost of virtual functions. In
> C++, it's up to you to choose.

Sorry, I obviously didn't read the proposal carefully. The proposal
wants to trade object size for increased (interface) pointer size.
That's not available in C++, at least, not with a nice syntax. I
think the proposal misses that you also need fat references, in order
to allow

(*interface_pointer).foo()

Cheers,
Dave

Dave Harris

unread,
Apr 13, 2004, 3:32:10 PM4/13/04
to
cdig...@videotron.ca ("christopher diggins") wrote (abridged):
> > How does an interface differ from an abstract base class? Can an
> > interface have non-pure virtual functions? Non-virtual functions?
> > Static member variables? Or are they just like in Java?

I would still like to see this answered. In my view you have not yet made
a case for your new feature.


> > Have you considered other implementation techniques for ABCs,
> > eg thunks, or cached searches?
>
> No, I am not concerned with ABC's specifically but how they are a poor
> substitute for an interface.

Why are they are poor substitute? It seems to me Java interfaces have
restrictions which make them less useful than C++ classes.


> > Can you prove that the only way to get performance is by using
> > the restricted form of interfaces?
>
> I can't prove that because it isn't true. There are lots of ways
> improving performance.

You just said your motivation was performance. If you can get the
performance of interfaces with ABCs, why do you want the new feature?

Maybe in, say, 5 or 10 years time, when all the compiler vendors have
"export" working properly and they have turned their attention to
optimisation, they will find better ways of implementing ABCs. Then
interfaces will not be necessary. Do you have any good reason for thinking
this cannot happen?

-- Dave Harris, Nottingham, UK

---

vze2...@verizon.net

unread,
Apr 13, 2004, 4:19:46 PM4/13/04
to

I have been thinking about the ways of implementing interfaces within the
framework of C++ while preserving all the features of the original proposal,
but have had no success so far. However I am still not convinced that features
offered by the proposal are valuable enough to warrant the language change.

The implementation that you suggested suffers one more disadvantage as compared
to OP's proposal. Interfaces, as proposed, would allow for the implementing
class to be very light weight, e.g. having no virtual methods or being POD.

With your implementation the class implementing an interface derives from
the interface class which means that the interface class must provide a
virtual destructor.

Also, it is natural to expect that a if A implements an interface and
B is derived from A, then B implicitly implements the interface. I can
not see how one can easily achieve it with your implementation. On the
other hand with the OP's proposal it can be done.

Anyway, some sort of polymorphysm can be achieved by adjusting your example in
the following way:

template< typename T > class if_base
{
public:

T & self() { return *static_cast< T * >( this ); }
const T & self() const { return *static_cast< const T * >( this ); }
};

template< typename T > class if_foo;

template<> class if_foo< void >
{
public:

virtual void foo() = 0;

virtual ~if_foo() {}
};


template< typename T >
class if_foo : public if_base< T >, public if_foo< void >
{
public:

void foo() { self().foo(); }
};

class foo_class : public if_foo< foo_class >
{
public:

void foo();
};

Unfortunately this requires foo() to be virtual (which actually
matches the default behavior in Jave, but Java provides "final"
modifier which, as far as I know, can not be implemented in C++).

The above implementation solves one problems with ABC's that is mentioned
in the proposal: the object size increase. In fact if foo_class has
virtual functions in the beginning, it actually saves memory, since
interface pointer is just an ordinary pointer rather than a fat pointer.
Otherwise it just adds one vtable pointer to the class which makes
it equivalent to a fat pointer.

Here is another possibility to implement interfaces, this time
using composition instead of inheritance:

template< typename T > class if_foo;

template<> class if_foo< void >
{
public:

virtual void foo() = 0;
virtual ~if_foo() {}
};

template< typename T >
class if_foo : public if_foo< void >
{
public:

if_foo( T & t ) : t_( t ) {}

void foo() { t.foo(); }

protected:

T & t_;
};

class foo_class
{
public:

void foo();
};

This would allow foo_class be as simple as necessary, and it solves
the problem of inheritance:

class foo_class
{
public:

virtual void foo();
virtual ~foo_class() {}
};

class derived : public foo_class
{
public:

void foo();
};

derived D;
foo_class & fc = D;
if_foo< void > * ifp = *new if_foo< foo_class >( fc );
ifp->foo(); // calls derived::foo()

But now ifp points to an object if_foo< foo_class > which contains a vtable ptr
and a reference to D which effectively makes it 3 pointers instead of 2 as in
fat pointer proposal.

Regards,

--
Aleksandr Morgulis
aleksandr...@verizon.net

---

christopher diggins

unread,
Apr 14, 2004, 8:38:02 PM4/14/04
to
"Pete Vidler" <pvi...@mailblocks.com> wrote in message
news:ysPec.40$xN...@newsfe1-gui.server.ntli.net...

> christopher diggins wrote:
> [snip]
> > The CRTP(?) approach does indeed have no virtual functions but is
lacking of
> > polymorphism on the interface because every "implementation" would have
a
> > different base type.
>
> CRTP = Curiously Recurring Template Pattern. The compile-time
> polymorphism is gained through the use of templates whenever you need to
> take different "interfaces".
>
> -- Pete

The term "compile-time polymorphism" is misleading. Historically the term
polymorphism is used to refer to objects taking different forms at runtime.
Calling the CRTP approach "compile-time polymorphism" is misleading,
especially in the context of implying that it is comparable to real
polymorphism.

---

christopher diggins

unread,
Apr 14, 2004, 8:38:15 PM4/14/04
to
"David Abrahams" <da...@boost-consulting.com> wrote in message
news:uk70k3...@boost-consulting.com...

> da...@boost-consulting.com (David Abrahams) writes:
>
> > Of course. You can't have it both ways: either you get type erasure,
> > dynamic polymorphism, and you pay the runtime cost of virtual
> > functions, or you preserve type distinctions, use static
> > polymorphism, and avoid the runtime cost of virtual functions. In
> > C++, it's up to you to choose.
>
> Sorry, I obviously didn't read the proposal carefully. The proposal
> wants to trade object size for increased (interface) pointer size.
> That's not available in C++, at least, not with a nice syntax. I
> think the proposal misses that you also need fat references, in order
> to allow
>
> (*interface_pointer).foo()

Sorry that I forgot to mention that in the proposal.
I would also propose not using interface reference types to have the same
semantics as pointers, but rather as a struct. This is because the idea of
dereferencing would be redundant.

interface_pointer.foo()

I would find that syntax preferable, but this is a minor point.

---

christopher diggins

unread,
Apr 15, 2004, 1:03:38 AM4/15/04
to
"Dave Harris" <bran...@cix.co.uk> wrote in message
news:memo.20040412231942.236A@brangdon.m...

> cdig...@videotron.ca ("christopher diggins") wrote (abridged):
> > > How does an interface differ from an abstract base class? Can an
> > > interface have non-pure virtual functions? Non-virtual functions?
> > > Static member variables? Or are they just like in Java?
>
> I would still like to see this answered. In my view you have not yet made
> a case for your new feature.

I am currently proposing interfaces that contain only member functions. Your
other suggestions (static member variables, non-pure virtual functions,
non-virtual functions) could all be potentially introduced later. I like
them all and see no reason not to include them, except that at this point it
would be perhaps premature to consider them.

> > > Have you considered other implementation techniques for ABCs,
> > > eg thunks, or cached searches?
> >
> > No, I am not concerned with ABC's specifically but how they are a poor
> > substitute for an interface.
>
> Why are they are poor substitute? It seems to me Java interfaces have
> restrictions which make them less useful than C++ classes.

I confused the issue from the beginning because of my poor introduction of
the proposal, for which I apologize. I meant to say that using ABC's as
interfaces is very inefficient. ABC's by themselves are useful and
important. I don't mean to compare interfaces with classes as such.
Interfaces have a very specific and useful purpose, to model certain kinds
of looks-like and behaves-like object relationships.

> > > Can you prove that the only way to get performance is by using
> > > the restricted form of interfaces?
> >
> > I can't prove that because it isn't true. There are lots of ways
> > improving performance.
>
> You just said your motivation was performance. If you can get the
> performance of interfaces with ABCs, why do you want the new feature?

Sorry, I wasn't sure to what performance you were addressing. My position is
that using an ABC to emulate an interface is inefficient.

> Maybe in, say, 5 or 10 years time, when all the compiler vendors have
> "export" working properly and they have turned their attention to
> optimisation, they will find better ways of implementing ABCs. Then
> interfaces will not be necessary. Do you have any good reason for thinking
> this cannot happen?

The whole problem stems from the fact that a implementing an interface is
not an implicit agreement to make those functions virtual (as it would be
when inheriting from an ABC). This problem can not be resolved by simply
making ABC's more efficient. Virtual functions by definition require more
time and memory than non-virtual functions.

---

Alberto Barbati

unread,
Apr 15, 2004, 11:16:37 AM4/15/04
to
christopher diggins wrote:
> I am currently proposing interfaces that contain only member functions. Your
> other suggestions (static member variables, non-pure virtual functions,
> non-virtual functions) could all be potentially introduced later. I like
> them all and see no reason not to include them, except that at this point it
> would be perhaps premature to consider them.
>
> [snips]

>
> The whole problem stems from the fact that a implementing an interface is
> not an implicit agreement to make those functions virtual (as it would be
> when inheriting from an ABC). This problem can not be resolved by simply
> making ABC's more efficient. Virtual functions by definition require more
> time and memory than non-virtual functions.
>

Those two sentences looks in contradiction to me. The first one suggests
that interface methods should be pure virtual by default (you said that
"non-virtual function could be potentially introduced later"). The
second sentence suggests that implementing an interface does not make
the methods implicitly virtual. Could you clarify your thought?

In fact, you have stressed several times in this thread that interface
member functions need not be virtual (you even said that "there is no
point to using virtual functions as it conflicts with the intent"). This
points strikes me. If you define an interface as:

---begin example
interface Runnable
{
void run();
};

class Base
{
public:
implement Runnable;
void run();
};

class Derived : public Base
{
public:
void run(); // does it override Base::run()?
};

int main()
{
Derived d;
Runnable rd = d; // or whatever syntax you have to get
// an interface reference from an object

d.run(); // Derived::run()
rd.run(); // which one? Base::run() or Derived::run() ?

Base& b = d;
Runnable rb = b;
rb.run(); // which one? Base::run() or Derived::run() ?
}
---end example

In this scenario, the most obvious thing, IMHO, is that run() should
behaves as-if it where implicitly declared as virtual, that is
Derived::run() should be called in all three places. A different
behaviour would violate the least-astonishment principle (for most Java
programmers at least ;)

Please notice that implementing non-virtual methods in interfaces is
more difficult than implementing virtual ones. Correct me if I'm wrong,
but to implement a non-virtual method correctly, the interface reference
should contain a pointer to each non-virtual method, thus each method in
the interface increases the size of the reference. As interfaces
references are meant to be passed by value, this looks like a nightmare
to me. On the other hand, to implement virtual methods, the size of a
reference would be exactly equal to two pointers (one to the object, one
to the vtable) regardless of the number of methods.

Even in case I'm missing something and there's a valid reason why
interface methods need not be virtual, my example shows that virtual
methods still have a reason to be and should be included in the proposal
right from the beginning.

Alberto

Bob Bell

unread,
Apr 15, 2004, 1:09:45 PM4/15/04
to
cdig...@videotron.ca ("christopher diggins") wrote in message news:<3rafc.164007$KE5.2...@weber.videotron.net>...

> "Pete Vidler" <pvi...@mailblocks.com> wrote in message
> news:ysPec.40$xN...@newsfe1-gui.server.ntli.net...
> > christopher diggins wrote:
> > [snip]
> > > The CRTP(?) approach does indeed have no virtual functions but is
> lacking of
> > > polymorphism on the interface because every "implementation" would have
> a
> > > different base type.
> >
> > CRTP = Curiously Recurring Template Pattern. The compile-time
> > polymorphism is gained through the use of templates whenever you need to
> > take different "interfaces".
> >
> > -- Pete
>
> The term "compile-time polymorphism" is misleading. Historically the term
> polymorphism is used to refer to objects taking different forms at runtime.
> Calling the CRTP approach "compile-time polymorphism" is misleading,
> especially in the context of implying that it is comparable to real
> polymorphism.

Not exactly. The term "polymorphism" simply means "many bodies".
Historically, polymorphism refers to the effect of having a single
syntactic construct that can be executed in multiple ways depending on
some kind of context. The term "polymorphism" got co-opted by the
object oriented programming movement, so now everyone thinks that
polymorphism mean some kind of run-time message dispatching scheme. A
consequence is that polymorphism at compile time gets a special name:
"compile time polymorphism".

A simple (and historical) example is "+".

x = y + z;

can execute different instructions depending on the type of y and z.
This is also an example of compile-time polymorphism since the
decision about which code to execute is made at compile time.

Bob

Pete Vidler

unread,
Apr 15, 2004, 1:47:44 PM4/15/04
to
christopher diggins wrote:
[snip]

> The term "compile-time polymorphism" is misleading. Historically the term
> polymorphism is used to refer to objects taking different forms at runtime.
> Calling the CRTP approach "compile-time polymorphism" is misleading,
> especially in the context of implying that it is comparable to real
> polymorphism.

From the dictionary definition of polymorphism (from www.m-w.com):

"the quality or state of being able to assume different forms"

I see this as applying to static (compile-time) polymorphism just as
well as it does to dynamic (run-time) polymorphism.

The two are comparable -- please explain what you mean when you say they
are not? They accomplish essentially the same thing (but at different
times).

-- Pete

llewelly

unread,
Apr 15, 2004, 1:48:48 PM4/15/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> "Pete Vidler" <pvi...@mailblocks.com> wrote in message
> news:ysPec.40$xN...@newsfe1-gui.server.ntli.net...
>> christopher diggins wrote:
>> [snip]
>> > The CRTP(?) approach does indeed have no virtual functions but is
> lacking of
>> > polymorphism on the interface because every "implementation" would have
> a
>> > different base type.
>>
>> CRTP = Curiously Recurring Template Pattern. The compile-time
>> polymorphism is gained through the use of templates whenever you need to
>> take different "interfaces".
>>
>> -- Pete
>
> The term "compile-time polymorphism" is misleading. Historically the term
> polymorphism is used to refer to objects taking different forms at runtime.
> Calling the CRTP approach "compile-time polymorphism" is misleading,

'compile-time' is clearly distinct from 'runtime'. It is thus obvious
that 'compile-time polymorphism' refers to a different property
than 'polymorphism'.

You are saying it is misleading to refer to a red rose as a 'red rose'.

> especially in the context of implying that it is comparable to real
> polymorphism.

Compile-time polymorphism and runtime polymorphism have overlapping
areas of use. Therefor they can be compared, within the area of
their overlap. It is not an apples-to-apples comparison; it is an
apples-to-pears comparison. Nonetheless both are fruits, so to
speak.

christopher diggins

unread,
Apr 15, 2004, 3:48:28 PM4/15/04
to
"Bob Bell" <bel...@pacbell.net> wrote in message
news:c87c1cfb.04041...@posting.google.com...

I am aware of the greek roots of the word as well the standard English
defintion. English definitions of words often have little meaning when
referring to programming techniques and concepts.

> Historically, polymorphism refers to the effect of having a single
> syntactic construct that can be executed in multiple ways depending on
> some kind of context.
>
> The term "polymorphism" got co-opted by the
> object oriented programming movement, so now everyone thinks that
> polymorphism mean some kind of run-time message dispatching scheme. A
> consequence is that polymorphism at compile time gets a special name:
> "compile time polymorphism".

I was not aware of the common usage of the term polymorphism predating the
object oriented movement. If this is the case then I withdraw my objection.

> A simple (and historical) example is "+".
>
> x = y + z;
>
> can execute different instructions depending on the type of y and z.
> This is also an example of compile-time polymorphism since the
> decision about which code to execute is made at compile time.
>
> Bob

I was under the understanding that this was commonly called operator
overloading. My relative youth in the field of computer science perhaps
betrays me in this discussion.

This discussion, while being very interesting and educational, does not
detract from my original point that bringing up the compile-time
polymorphism of CRTP in comparison with the run-time polymorphism of
interfaces is not a fair and accurate comparison because they are different
techniques which can not be used interchangeably.

I was perhaps wrong in attributing this error of comparison with what I may
have mistakenly perceived as a poor choice of terms.

---

Matthew Collett

unread,
Apr 15, 2004, 7:09:39 PM4/15/04
to
In article <%Cafc.573$uc7....@weber.videotron.net>,

cdig...@videotron.ca ("christopher diggins") wrote:

> The whole problem stems from the fact that a implementing an interface is
> not an implicit agreement to make those functions virtual (as it would be
> when inheriting from an ABC). This problem can not be resolved by simply
> making ABC's more efficient. Virtual functions by definition require more
> time and memory than non-virtual functions.

If I have understood correctly what you are after, it seems to be a
special case of something rather simpler and more general, namely the
ability to say that a virtual function is no longer so (or rather, can
no longer be overridden). In effect, the job could be done by giving
C++ something like Java's 'final' for functions. Assuming the notation
'~virtual' to avoid introducing another keyword:

class AnInterface { //Just an ABC, as at present
public:
virtual void aFunction() = 0;
}

class AnImplementation: public AnInterface {
public:
~virtual void aFunction(); //Prevents further overriding
}

Anything which has a pointer/reference to AnInterface then uses the
usual virtual dispatch mechanism (and despite what you say above, I
cannot see how interfaces can be implemented without something
effectively equivalent to virtual dispatch), while anything which has a
pointer/reference to AnImplementation could use direct (non-virtual)
dispatching instead.

Best wishes,
Matthew Collett

--
Those who assert that the mathematical sciences have nothing to say
about the good or the beautiful are mistaken. -- Aristotle

christopher diggins

unread,
Apr 15, 2004, 8:46:21 PM4/15/04
to
"Alberto Barbati" <Alberto...@libero.it> wrote in message
news:3vtfc.3575$Qc.1...@twister1.libero.it...

> christopher diggins wrote:
> > I am currently proposing interfaces that contain only member functions.
Your
> > other suggestions (static member variables, non-pure virtual functions,
> > non-virtual functions) could all be potentially introduced later. I like
> > them all and see no reason not to include them, except that at this
point it
> > would be perhaps premature to consider them.
> >
> > [snips]
> >
> > The whole problem stems from the fact that a implementing an interface
is
> > not an implicit agreement to make those functions virtual (as it would
be
> > when inheriting from an ABC). This problem can not be resolved by simply
> > making ABC's more efficient. Virtual functions by definition require
more
> > time and memory than non-virtual functions.
> >
>
> Those two sentences looks in contradiction to me. The first one suggests
> that interface methods should be pure virtual by default (you said that
> "non-virtual function could be potentially introduced later"). The
> second sentence suggests that implementing an interface does not make
> the methods implicitly virtual. Could you clarify your thought?

You are correct, the sentence which refers to virtual functions is wrong.
Perhaps inserting "virtual-like" would clarify its intent.

> In fact, you have stressed several times in this thread that interface
> member functions need not be virtual (you even said that "there is no
> point to using virtual functions as it conflicts with the intent").

I stand by this statement.

> This points strikes me. If you define an interface as:
>
> ---begin example
> interface Runnable
> {
> void run();
> };
>
> class Base
> {
> public:
> implement Runnable;
> void run();
> };
>
> class Derived : public Base
> {
> public:
> void run(); // does it override Base::run()?
> };

Not according to the proposal.

> int main()
> {
> Derived d;
> Runnable rd = d; // or whatever syntax you have to get
> // an interface reference from an object

That is exactly the syntax I was thinking of.

> d.run(); // Derived::run()
> rd.run(); // which one? Base::run() or Derived::run() ?

Base::run because Derived doesn't implement Runnable, but Base does. Derived
could implement Runnable as well if it wanted to have its own implementation
executed.

> Base& b = d;
> Runnable rb = b;
> rb.run(); // which one? Base::run() or Derived::run() ?

Base::run again for the same reasons above.

> In this scenario, the most obvious thing, IMHO, is that run() should
> behaves as-if it where implicitly declared as virtual, that is
> Derived::run() should be called in all three places. A different
> behaviour would violate the least-astonishment principle (for most Java
> programmers at least ;)

If any implementation of Java performs in that manner it is incorrectly
implemented according to the java virtual machine specification of
invokeinterface bytecodes:

http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.html#invokeinterface

I would venture to say that the reason the implicit virtual behaviour is
obvious to you (and many others) is because as C++ programmers we are used
to working with virtual functions. I would argue that from a more naive
standpoint, an interface behaving as virtual itself violates the
least-astonishment principle.

> Please notice that implementing non-virtual methods in interfaces is
> more difficult than implementing virtual ones.

Not difficult really, I banged out an implementation in a few days
(http://www.heron-language.com/heronfront.html )

> Correct me if I'm wrong,
> but to implement a non-virtual method correctly, the interface reference
> should contain a pointer to each non-virtual method, thus each method in
> the interface increases the size of the reference.

I use an extra pointer in the interface reference to a static table of
method pointers. You only need one table for each class/interface pair.

> As interfaces
> references are meant to be passed by value, this looks like a nightmare
> to me. On the other hand, to implement virtual methods, the size of a
> reference would be exactly equal to two pointers (one to the object, one
> to the vtable) regardless of the number of methods.

I use the same approach to implementing the proposed non-virtual interfaces
in HeronFront.

> Even in case I'm missing something and there's a valid reason why
> interface methods need not be virtual, my example shows that virtual
> methods still have a reason to be and should be included in the proposal
> right from the beginning.

That is correct and the original proposal was very badly written. I
shouldn't have suggested in the proposal that interfaces would replace
ABC's, but rather they would replace using ABC's as interfaces.

By the way have you looked at the most recent proposal where I take into
account your syntax suggestions? http://www.heron-language.com/cpp-iop.html

---

llewelly

unread,
Apr 15, 2004, 8:51:31 PM4/15/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> "Bob Bell" <bel...@pacbell.net> wrote in message

[snip]


>> A simple (and historical) example is "+".
>>
>> x = y + z;
>>
>> can execute different instructions depending on the type of y and z.
>> This is also an example of compile-time polymorphism since the
>> decision about which code to execute is made at compile time.
>>
>> Bob
>
> I was under the understanding that this was commonly called operator
> overloading. My relative youth in the field of computer science perhaps
> betrays me in this discussion.

[snip]

Overloading is a kind of polymorphism.

Adam H. Peterson

unread,
Apr 15, 2004, 10:38:02 PM4/15/04
to
> I meant to say that using ABC's as
> interfaces is very inefficient. ABC's by themselves are useful and
> important. I don't mean to compare interfaces with classes as such.
> Interfaces have a very specific and useful purpose, to model certain kinds
> of looks-like and behaves-like object relationships.

From a functionality stand point, it looks to me like ABC functionality
is are a proper superset of interface functionality. From a performance
standpoint, I don't see how ABCs have an obvious asymptotic performance
hit. They look to me like they are pretty equivalent in terms of
performance (if that). That may not be true, but I feel it needs to be
demonstrated more conclusively to justify the addition of a reduced
functionality version of a language feature because of performance concerns.


> Virtual functions by definition require more
> time and memory than non-virtual functions.
>

Which definition of virtual functions are you using? I've never heard a
definition for virtual function that included a performance hit as a
criterion. Perhaps a performance hit can be deduced from the
definition, but I'm not convinced of that either.

Matt Austern

unread,
Apr 15, 2004, 10:38:25 PM4/15/04
to
pvi...@mailblocks.com (Pete Vidler) writes:

> christopher diggins wrote:
> [snip]
> > The term "compile-time polymorphism" is misleading. Historically the term
> > polymorphism is used to refer to objects taking different forms at runtime.
> > Calling the CRTP approach "compile-time polymorphism" is misleading,
> > especially in the context of implying that it is comparable to real
> > polymorphism.
>
> From the dictionary definition of polymorphism (from www.m-w.com):
>
> "the quality or state of being able to assume different forms"
>
> I see this as applying to static (compile-time) polymorphism just as
> well as it does to dynamic (run-time) polymorphism.

You don't have to resort to dictionary definitions to show that: you
can point to the computer science literature! For example, you can
point to the famous paper by Cardelli and Wegner, "On Understanding
Types, Data Abstraction, and Polymorphism". They distinguish between
"universal" and "ad-hoc" polymorphism (where "ad-hoc" includes things
like overloading), and, within universal polymorphism, they
distinguish between parametric and inclusion polymorphism.

C++ templates are a perfectly good example of parametric polymorphism.

Bart van Ingen Schenau

unread,
Apr 16, 2004, 11:27:04 AM4/16/04
to
On Fri, 16 Apr 2004 00:46:21 +0000 (UTC), cdig...@videotron.ca
("christopher diggins") wrote:

>"Alberto Barbati" <Alberto...@libero.it> wrote in message
>news:3vtfc.3575$Qc.1...@twister1.libero.it...
>> christopher diggins wrote:
>
>> In this scenario, the most obvious thing, IMHO, is that run() should
>> behaves as-if it where implicitly declared as virtual, that is
>> Derived::run() should be called in all three places. A different
>> behaviour would violate the least-astonishment principle (for most Java
>> programmers at least ;)
>
>If any implementation of Java performs in that manner it is incorrectly
>implemented according to the java virtual machine specification of
>invokeinterface bytecodes:
>
>http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.html#invokeinterface

That is not how I interpret that specification.
The invokeinterface opcode has as parameter a reference to an object,
and the method to invoke is first looked up in that object and after
that, if it wasn't found, in any base-class of that object.

This suggests to me that an implements relation is inherited by
derived classes in Java.

Bart v Ingen Schenau

christopher diggins

unread,
Apr 16, 2004, 1:39:34 PM4/16/04
to
"Matthew Collett" <m.co...@auckland.ac.nz> wrote in message
news:m.collett-F970C...@lust.ihug.co.nz...

> In article <%Cafc.573$uc7....@weber.videotron.net>,
> cdig...@videotron.ca ("christopher diggins") wrote:
>
> > The whole problem stems from the fact that a implementing an interface
is
> > not an implicit agreement to make those functions virtual (as it would
be
> > when inheriting from an ABC). This problem can not be resolved by simply
> > making ABC's more efficient. Virtual functions by definition require
more
> > time and memory than non-virtual functions.
>
> If I have understood correctly what you are after, it seems to be a
> special case of something rather simpler and more general, namely the
> ability to say that a virtual function is no longer so (or rather, can
> no longer be overridden).
>
> In effect, the job could be done by giving
> C++ something like Java's 'final' for functions. Assuming the notation
> '~virtual' to avoid introducing another keyword:
>
> class AnInterface { //Just an ABC, as at present
> public:
> virtual void aFunction() = 0;
> }
>
> class AnImplementation: public AnInterface {
> public:
> ~virtual void aFunction(); //Prevents further overriding
> }


This is not what I am striving towards. Interfaces should not imply
virtualization of implementing functions in the first place. What you
propose is a "covering one's tracks" approach to the problem at hand.

> Anything which has a pointer/reference to AnInterface then uses the
> usual virtual dispatch mechanism (and despite what you say above, I
> cannot see how interfaces can be implemented without something
> effectively equivalent to virtual dispatch), while anything which has a
> pointer/reference to AnImplementation could use direct (non-virtual)
> dispatching instead.

The dispatch of a method invocation clearly must be dynamic when referring
to an object by its interface but not when referring to an object by its
concrete type. That is what is exploited by the proposal at
http://www.heron-language.com/heronfront.html

---

christopher diggins

unread,
Apr 16, 2004, 1:39:50 PM4/16/04
to
""Adam H. Peterson"" <ah...@email.byu.edu> wrote in message
news:c5nb0c$2pqk$1...@acs2.byu.edu...

> > I meant to say that using ABC's as
> > interfaces is very inefficient. ABC's by themselves are useful and
> > important. I don't mean to compare interfaces with classes as such.
> > Interfaces have a very specific and useful purpose, to model certain
kinds
> > of looks-like and behaves-like object relationships.
>
> From a functionality stand point, it looks to me like ABC functionality
> is are a proper superset of interface functionality.

This is not the case in Java interfaces, and from a naive non-language
specific interpretation of what an interface should be. Given class C
implementing function F of interface I it would then surprise a [non C++
biased] programmer to have the function F become implicitly virtual.

> From a performance
> standpoint, I don't see how ABCs have an obvious asymptotic performance
> hit.

The problem occurs when implementing multiple bases (see
http://www.heron-language.com/heronfront.html for specific examples)

> They look to me like they are pretty equivalent in terms of
> performance (if that). That may not be true, but I feel it needs to be
> demonstrated more conclusively to justify the addition of a reduced
> functionality version of a language feature because of performance
concerns.

See the above link.

> > Virtual functions by definition require more
> > time and memory than non-virtual functions.
> >
>
> Which definition of virtual functions are you using? I've never heard a
> definition for virtual function that included a performance hit as a
> criterion. Perhaps a performance hit can be deduced from the
> definition, but I'm not convinced of that either.

Technically it is incorrect for me to have stated "... by defintion ...".
Nonetheless a virtual function call requires a dynamic dispatch of the
method. This in turn absolutely requires an extra operation to perform the
lookup (or calculate offset) and memory to store a dispatch table.

---

christopher diggins

unread,
Apr 16, 2004, 1:40:25 PM4/16/04
to
"Bart van Ingen Schenau" <Bart.van.In...@ict.nl> wrote in message
news:3c7v7015nr4lq2nod...@4ax.com...

> On Fri, 16 Apr 2004 00:46:21 +0000 (UTC), cdig...@videotron.ca
> ("christopher diggins") wrote:
>
> >"Alberto Barbati" <Alberto...@libero.it> wrote in message
> >news:3vtfc.3575$Qc.1...@twister1.libero.it...
> >> christopher diggins wrote:
> >
> >> In this scenario, the most obvious thing, IMHO, is that run() should
> >> behaves as-if it where implicitly declared as virtual, that is
> >> Derived::run() should be called in all three places. A different
> >> behaviour would violate the least-astonishment principle (for most Java
> >> programmers at least ;)
> >
> >If any implementation of Java performs in that manner it is incorrectly
> >implemented according to the java virtual machine specification of
> >invokeinterface bytecodes:
> >
>
>http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.h
tml#invokeinterface
>
> That is not how I interpret that specification.
> The invokeinterface opcode has as parameter a reference to an object,
> and the method to invoke is first looked up in that object and after
> that, if it wasn't found, in any base-class of that object.
>
> This suggests to me that an implements relation is inherited by
> derived classes in Java.


The implements relation is indeed inherited but the interface functions
remain bound to the base class as opposed to being dispatch to any
overloaded versions in the superclass. Hence my assertion that the interface
function is not made implicitly virtual.

---

llewelly

unread,
Apr 16, 2004, 6:45:15 PM4/16/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> ""Adam H. Peterson"" <ah...@email.byu.edu> wrote in message

[snip]


>> Which definition of virtual functions are you using? I've never heard a
>> definition for virtual function that included a performance hit as a
>> criterion. Perhaps a performance hit can be deduced from the
>> definition, but I'm not convinced of that either.
>
> Technically it is incorrect for me to have stated "... by defintion ...".
> Nonetheless a virtual function call requires a dynamic dispatch of the
> method. This in turn absolutely requires an extra operation to perform the
> lookup (or calculate offset) and memory to store a dispatch table.

More importantly, virtual functions (a) are not generally be inlined,
(b) require indirect function calls which are more likely to miss
in the Icache, and (c) on some processors require longer pipeline
stalls.

But it seems to me that it is rare for a virtual function call to end
up in a bottleneck. In my experience the C++ features which cause
the most performance or memory overhead problems have been
iostreams, std::string, new, and on some platforms, exception
handling. Virtual functions have never mattered as much as any of
these. Arguably (certainly in the case of iostream) this is
due to less-than-ideal implementations of said features, but I
think I've usually been facing less-than-ideal implementations of
virtual functions too.

llewelly

unread,
Apr 16, 2004, 6:46:12 PM4/16/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> "Bart van Ingen Schenau" <Bart.van.In...@ict.nl> wrote in message
> news:3c7v7015nr4lq2nod...@4ax.com...

[snip]


>>http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.h
> tml#invokeinterface
>>
>> That is not how I interpret that specification.
>> The invokeinterface opcode has as parameter a reference to an object,
>> and the method to invoke is first looked up in that object and after
>> that, if it wasn't found, in any base-class of that object.
>>
>> This suggests to me that an implements relation is inherited by
>> derived classes in Java.
>
>
> The implements relation is indeed inherited but the interface functions
> remain bound to the base class as opposed to being dispatch to any
> overloaded versions in the superclass.

First, a C++ Base class is roughly equivalent to a Java
superclass. I point this out because seems to me you mean
'derived class' where you say 'superclass'.

Second, a Java call to a method through an interface *does* dispatch
to the method defined in the most derived class, see
http://xrl.us/bwh5 I point this out because it is unclear to me
whether you are talking about Java interfaces or heronfront
interfaces.

> Hence my assertion that the interface
> function is not made implicitly virtual.

And this makes heronfront interfaces different from Java interfaces
(as well as different from C++ ABCs).

christopher diggins

unread,
Apr 17, 2004, 12:07:29 AM4/17/04
to
"llewelly" <llewe...@xmission.dot.com> wrote in message
news:86zn9bi...@Zorthluthik.local.bar...

> cdig...@videotron.ca ("christopher diggins") writes:
>
> > "Bart van Ingen Schenau" <Bart.van.In...@ict.nl> wrote in
message
> > news:3c7v7015nr4lq2nod...@4ax.com...
> [snip]
>
>>http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.
h
> > tml#invokeinterface
> >>
> >> That is not how I interpret that specification.
> >> The invokeinterface opcode has as parameter a reference to an object,
> >> and the method to invoke is first looked up in that object and after
> >> that, if it wasn't found, in any base-class of that object.
> >>
> >> This suggests to me that an implements relation is inherited by
> >> derived classes in Java.
> >
> >
> > The implements relation is indeed inherited but the interface functions
> > remain bound to the base class as opposed to being dispatch to any
> > overloaded versions in the superclass.
>
> First, a C++ Base class is roughly equivalent to a Java
> superclass. I point this out because seems to me you mean
> 'derived class' where you say 'superclass'.

My mistake, thank you for correcting that.

> Second, a Java call to a method through an interface *does* dispatch
> to the method defined in the most derived class, see
> http://xrl.us/bwh5 I point this out because it is unclear to me
> whether you are talking about Java interfaces or heronfront
> interfaces.

The link you give does not support your statement in any way. It makes no
reference as to the resolution of interface method invocation. It refers to
two forms of function overloads: non-abstract function overrides and
abstract function implementation.

Please read carefully:
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.html#invokeinterface

Specifically:

a.. If C contains a declaration for an instance method with the same name
and descriptor as the resolved method, then this is the method to be
invoked, and the lookup procedure terminates.

a.. Otherwise, if C has a superclass, this same lookup procedure is
performed recursively using the direct superclass of C; the method to be
invoked is the result of the recursive invocation of this lookup procedure.

This is very explicit.

> > Hence my assertion that the interface
> > function is not made implicitly virtual.
>
> And this makes heronfront interfaces different from Java interfaces
> (as well as different from C++ ABCs).

No it doesn't.

- Christopher Diggins

David Abrahams

unread,
Apr 17, 2004, 1:36:43 PM4/17/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> "David Abrahams" <da...@boost-consulting.com> wrote in message
> news:uk70k3...@boost-consulting.com...
>> da...@boost-consulting.com (David Abrahams) writes:
>>
>> > Of course. You can't have it both ways: either you get type erasure,
>> > dynamic polymorphism, and you pay the runtime cost of virtual
>> > functions, or you preserve type distinctions, use static
>> > polymorphism, and avoid the runtime cost of virtual functions. In
>> > C++, it's up to you to choose.
>>
>> Sorry, I obviously didn't read the proposal carefully. The proposal
>> wants to trade object size for increased (interface) pointer size.
>> That's not available in C++, at least, not with a nice syntax. I
>> think the proposal misses that you also need fat references, in order
>> to allow
>>
>> (*interface_pointer).foo()
>
> Sorry that I forgot to mention that in the proposal.
> I would also propose not using interface reference types to have the same
> semantics as pointers, but rather as a struct. This is because the idea of
> dereferencing would be redundant.
>
> interface_pointer.foo()
>
> I would find that syntax preferable, but this is a minor point.

You misinterpreted my point. I wasn't suggesting that interface
references have the same syntax as pointers. My point was that even
if you don't like references, if you can apply operator* to an
interface pointer you have to say what type that is. So your
interface pointers lead inevitably to interface references.

Incidentally, I believe that nothing prevents an implementation from
making an optimization like the one you desire for ABCs today, that
the "interface" keyword is probably unneeded, and that your proposal's
standard language is probably phrased way too much in terms of
low-level details that may not be appropriate to any particular
implementation and not enough in terms of the abstract C++ machine.

For example, at the crudest level, all data pointer types could be
made large enough to hold the addresses of an object and a function
table, to satisfy the standard requirements on round-trip pointer
conversions. Then the compiler could decide to represent abstract
class pointers the way you'd like.

A slightly fancier approach might add an extra level of indirection to
interface pointers:

+---+ +---+---+
| -+--->| , | , |
+---+ +-+-+-+-+ +-----------+
| | | |
| +--------->| object |
| | |
V +-----------+
+-------------+
| |
| function |
| table |
| |
+-------------+

I think you should be looking for those places in the current
standard that may prevent the optimization you're after, and think
about ways to loosen the restrictions appropriately.

Cheers,

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

---

llewelly

unread,
Apr 17, 2004, 6:54:06 PM4/17/04
to

We drifting off-topic here, but in both C++ and Java, for one member
function to override and inherited member function means the
overriding method will be selected in dynamic dispatch.

The link I provided is about overriding, and overriding is about
method invocation. It is a concept which has no meaning (at least
not in C++ or Java) in the absense of dynamic dispatch.

> It refers to
> two forms of function overloads: non-abstract function overrides and
> abstract function implementation.
>
> Please read carefully:
> http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.html#invokeinterface
>
> Specifically:
>
> a.. If C contains a declaration for an instance method with the same name
> and descriptor as the resolved method, then this is the method to be
> invoked, and the lookup procedure terminates.
>
> a.. Otherwise, if C has a superclass, this same lookup procedure is
> performed recursively using the direct superclass of C; the method to be
> invoked is the result of the recursive invocation of this lookup procedure.
>
> This is very explicit.

But to me it seems an explicit description of *dynamic*
dispatch. What am I missing?

Please explain why you do not think this is equivalent to C++
virtual. (Note, I hadn't read this post of yours when I quoted
this same text at you in the thread on comp.lang.c++.moderated.)

christopher diggins

unread,
Apr 18, 2004, 2:27:08 PM4/18/04
to
"llewelly" <llewe...@xmission.dot.com> wrote in message
news:86isfya...@Zorthluthik.local.bar...


I sincerely apologize. I made the mistake of confusing superclass with
subclass *again*. So Java interfaces are indeed identical to abstract base
classes (which astounds me). Nonetheless I still think that the HeronFront
interpretation of interfaces is theroetically correct in the context of C++.
When as a programmer I say a class implements an interface it is not an
implicit agreement to make those functions virtual.

---

Ben Hutchings

unread,
Apr 19, 2004, 1:34:42 PM4/19/04
to
"christopher diggins" wrote:
> "Bart van Ingen Schenau" <Bart.van.In...@ict.nl> wrote in message
> news:3c7v7015nr4lq2nod...@4ax.com...
<snip>

>> This suggests to me that an implements relation is inherited by
>> derived classes in Java.
>
> The implements relation is indeed inherited but the interface functions
> remain bound to the base class as opposed to being dispatch to any
> overloaded versions in the superclass.

You mean overridden, or else you are *very* confused.

> Hence my assertion that the interface function is not made
> implicitly virtual.

Please compile and run this program:

public class test {
private interface I { String answer(); }
private class sup implements I {
public String answer() { return "right"; }
}
private class sub extends sup {
public String answer() { return "wrong"; }
}
private void answer() {
I i = new sub();
System.out.println("Diggins is " + i.answer());
}
public static void main(String[] args) {
(new test()).answer();

llewelly

unread,
Apr 19, 2004, 1:34:49 PM4/19/04
to
cdig...@videotron.ca ("christopher diggins") writes:

> "llewelly" <llewe...@xmission.dot.com> wrote in message
> news:86isfya...@Zorthluthik.local.bar...
>> cdig...@videotron.ca ("christopher diggins") writes:
>> > Please read carefully:
>> >
> http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc6.html#invokeinterface
>> >
>> > Specifically:
>> >
>> > a.. If C contains a declaration for an instance method with the same
> name
>> > and descriptor as the resolved method, then this is the method to be
>> > invoked, and the lookup procedure terminates.
>> >
>> > a.. Otherwise, if C has a superclass, this same lookup procedure is
>> > performed recursively using the direct superclass of C; the method to be
>> > invoked is the result of the recursive invocation of this lookup
> procedure.
>> >
>> > This is very explicit.
>>
>> But to me it seems an explicit description of *dynamic*
>> dispatch. What am I missing?
>>
>> Please explain why you do not think this is equivalent to C++
>> virtual. (Note, I hadn't read this post of yours when I quoted
>> this same text at you in the thread on comp.lang.c++.moderated.)
>
>
> I sincerely apologize. I made the mistake of confusing superclass with
> subclass *again*.

They confuse me too; I don't post anything that includes those two
terms without double checking them. And we aren't alone;
Stroustrup in D&E 2.9 says he chose 'base' and 'derived' because
he could never remember which of super and sub was which. I also
sometimes trip over the fact that in Java terminology 'type' is
equivalent to C++ 'static type' while 'class' is equivalent C++
'dynamic type'.

> So Java interfaces are indeed identical to abstract base
> classes (which astounds me).

It makes a certain kind of sense. Putting '=0' at the end of a member
function decl to declare an abstract base class is IMO really
weird!

> Nonetheless I still think that the HeronFront
> interpretation of interfaces is theroetically correct in the context
> of C++.

[snip]

It's not an issue of 'correctness' per se, it's 'is this usefull
enough to pay for the cost of adding a new feature?' FWIW,
heronFront interfaces seem much like (but not exactly) the
signatures extension gcc had years ago (as someone mentioned
earlier), see
http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_5.html#SEC112 .

Signatures were found to be little used and hard to maintain, (IIRC)
and so were removed from gcc.

christopher diggins

unread,
Apr 19, 2004, 4:34:27 PM4/19/04
to
"Ben Hutchings" <do-not-s...@bwsint.com> wrote in message
news:slrnc85h0c.gkv....@shadbolt.i.decadentplace.org.uk...

> "christopher diggins" wrote:
> > "Bart van Ingen Schenau" <Bart.van.In...@ict.nl> wrote in
message
> > news:3c7v7015nr4lq2nod...@4ax.com...
> <snip>
> >> This suggests to me that an implements relation is inherited by
> >> derived classes in Java.
> >
> > The implements relation is indeed inherited but the interface functions
> > remain bound to the base class as opposed to being dispatch to any
> > overloaded versions in the superclass.
>
> You mean overridden, or else you are *very* confused.


You are correct, I was misguided. I confused my superclass and subclass. I
apologize.

---

Stanley Friesen

unread,
Apr 19, 2004, 5:44:38 PM4/19/04
to
llewe...@xmission.dot.com (llewelly) wrote in message news:<86llkvk...@Zorthluthik.local.bar>...

> But it seems to me that it is rare for a virtual function call to end
> up in a bottleneck. In my experience the C++ features which cause
> the most performance or memory overhead problems have been
> iostreams, std::string, new, and on some platforms, exception
> handling. Virtual functions have never mattered as much as any of
> these. Arguably (certainly in the case of iostream) this is
> due to less-than-ideal implementations of said features, but I
> think I've usually been facing less-than-ideal implementations of
> virtual functions too.

I have to agree. I cannot remember virtual calls ever being a
signficant performance issue, and I am doing real-time programming.
Now, new *is* a major performance problem on the systems I am using,
and I have had to ban it from critical path code.

christopher diggins

unread,
Apr 20, 2004, 4:55:54 PM4/20/04
to
"llewelly" <llewe...@xmission.dot.com> wrote in message
news:868ygt2...@Zorthluthik.local.bar...

> cdig...@videotron.ca ("christopher diggins") writes:
>
> > "llewelly" <llewe...@xmission.dot.com> wrote in message
[snip]
>
> It's not an issue of 'correctness' per se, it's 'is this usefull
> enough to pay for the cost of adding a new feature?' FWIW,
> heronFront interfaces seem much like (but not exactly) the
> signatures extension gcc had years ago (as someone mentioned
> earlier), see
> http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_5.html#SEC112 .
>
> Signatures were found to be little used and hard to maintain, (IIRC)
> and so were removed from gcc.

Signatures are very similar, and I note that in my most recent proposal
(http://www.heron-language.com/cpp-iop.html ) But I wish to point out that
there are good reasons why people would not use a compiler specific language
extension and it doesn't discount the inherent value of my particular
proposal.

Here is my argument in a nutshell on why an interface feature would be
useful in order of importance:

1) multiple inheritance of abstract base classes comes at the cost of
linearly increasing object memory footprints which is both unacceptable and
unnecessary, when we are simply trying to model behaves-like or looks-like
object relationships

2) using abstract base classes to model interfaces comes at an unecessary
performance cost within the object

3) saying that class C implements interface I should not be an implicit
agreement to make those function virtual.

---

christopher diggins

unread,
Apr 20, 2004, 6:18:36 PM4/20/04
to
"David Abrahams" <da...@boost-consulting.com> wrote in message
news:uisfye...@boost-consulting.com...

I still miss your point then. The proposal is for a type (call it whatever
you want) that can refer to any object that implements a particular set of
function signatures. Calling it a pointer or a reference would be
misleading. This type can not be dereferenced.

> Incidentally, I believe that nothing prevents an implementation from
> making an optimization like the one you desire for ABCs today, that
> the "interface" keyword is probably unneeded, and that your proposal's
> standard language is probably phrased way too much in terms of
> low-level details that may not be appropriate to any particular
> implementation and not enough in terms of the abstract C++ machine.

What I am talking about has nothing to do with ABC's. It has nothing to do
neither with virtual functions. I am sorry if I have made it sound that way.
It is a way to refer to objects which implement a particular interface.

> For example, at the crudest level, all data pointer types could be
> made large enough to hold the addresses of an object and a function
> table, to satisfy the standard requirements on round-trip pointer
> conversions. Then the compiler could decide to represent abstract
> class pointers the way you'd like.

I don't see the advantage to having all data pointer types grow simply to
accomodate efficient interface pointers.

> A slightly fancier approach might add an extra level of indirection to
> interface pointers:
>
> +---+ +---+---+
> | -+--->| , | , |
> +---+ +-+-+-+-+ +-----------+
> | | | |
> | +--------->| object |
> | | |
> V +-----------+
> +-------------+
> | |
> | function |
> | table |
> | |
> +-------------+

What would the advantage of that be over:

+---+---+
| , | , |


+-+-+-+-+ +-----------+
| | | |
| +--------->| object |
| | |
V +-----------+
+-------------+
| |
| function |
| table |
| |
+-------------+


> I think you should be looking for those places in the current
> standard that may prevent the optimization you're after, and think
> about ways to loosen the restrictions appropriately.
>
> Cheers,

I am looking for much more than an optimization: I am looking for a feasable
way to model objects that have many different behaves-like relationships
(i.e. interfaces)

---

llewelly

unread,
Apr 21, 2004, 11:08:40 AM4/21/04
to
cdig...@videotron.ca ("christopher diggins") writes:

[snip]


> Signatures are very similar, and I note that in my most recent proposal
> (http://www.heron-language.com/cpp-iop.html )

[snip]

I'm sorry, I don't see any mention of signatures on that web
page. Maybe you forgot to update it?

Adam H. Peterson

unread,
Apr 21, 2004, 3:31:50 PM4/21/04
to
>>Signatures were found to be little used and hard to maintain, (IIRC)
>> and so were removed from gcc.
>
>
> Signatures are very similar, and I note that in my most recent proposal
> (http://www.heron-language.com/cpp-iop.html ) But I wish to point out that
> there are good reasons why people would not use a compiler specific language
> extension and it doesn't discount the inherent value of my particular
> proposal.

There are other platform/compiler specific features of many compilers
(gcc included) that people still find valuable enough to use, and which
nonetheless haven't made their way into the standard. I think the fact
that signatures were dropped _does_ discount their value to some degree.

>
> Here is my argument in a nutshell on why an interface feature would be
> useful in order of importance:
>
> 1) multiple inheritance of abstract base classes comes at the cost of
> linearly increasing object memory footprints which is both unacceptable and
> unnecessary, when we are simply trying to model behaves-like or looks-like
> object relationships

I don't understand how you can call an extra vtable pointer a linear
increase in object size. The object doesn't double in size just because
it has a fork in its ancestry.

>
> 2) using abstract base classes to model interfaces comes at an unecessary
> performance cost within the object

There are trade offs, but I think it's dubious to claim without some
substantial support that the proposal's trade off is better than ABC's
trade off. It looks to me like you're trading off a vtable pointer per
object for an entire chunk of the vtable per reference. And the
interface proposal is going to be using a form of dynamic dispatch as well.

>
> 3) saying that class C implements interface I should not be an implicit
> agreement to make those function virtual.

Maybe. But what's the harm in making them virtual? If there is a
serious potential problem with such functions being virtual, it looks to
me like a proposal to add "final" to the language would be more
appropriate. It would be more general than interfaces, which for the
most part allow you to do what you can already do with ABCs (minus the
non-virtual part).

christopher diggins

unread,
Apr 23, 2004, 7:01:56 PM4/23/04
to
""Adam H. Peterson"" <ah...@email.byu.edu> wrote in message
news:c64lv1$1kju$1...@acs2.byu.edu...

> >>Signatures were found to be little used and hard to maintain, (IIRC)
> >> and so were removed from gcc.
> >
> >
> > Signatures are very similar, and I note that in my most recent proposal
> > (http://www.heron-language.com/cpp-iop.html ) But I wish to point out
that
> > there are good reasons why people would not use a compiler specific
language
> > extension and it doesn't discount the inherent value of my particular
> > proposal.
>
> There are other platform/compiler specific features of many compilers
> (gcc included) that people still find valuable enough to use, and which
> nonetheless haven't made their way into the standard. I think the fact
> that signatures were dropped _does_ discount their value to some degree.
>
> > Here is my argument in a nutshell on why an interface feature would be
> > useful in order of importance:
> >
> > 1) multiple inheritance of abstract base classes comes at the cost of
> > linearly increasing object memory footprints which is both unacceptable
and
> > unnecessary, when we are simply trying to model behaves-like or
looks-like
> > object relationships
>
> I don't understand how you can call an extra vtable pointer a linear
> increase in object size. The object doesn't double in size just because
> it has a fork in its ancestry.

An extra vtable pointer is typically (for most C++ compilers) added to an
object for each virtual base. That is why I said linear. This may be an
implementation choice, but without it would come at a cost of more expensive
vtable dispatches.

> > 2) using abstract base classes to model interfaces comes at an
unecessary
> > performance cost within the object
>
> There are trade offs, but I think it's dubious to claim without some
> substantial support that the proposal's trade off is better than ABC's
> trade off.

In some cases, but not all. I don't mean to imply that interfaces are flat
out better than ABC's.

> It looks to me like you're trading off a vtable pointer per
> object for an entire chunk of the vtable per reference. And the
> interface proposal is going to be using a form of dynamic dispatch as
well.

The proposed implementation only places a single pointer in each interface
reference irregardless of the number of interfaces it may be composed of, or
that the object may implement. These "fat pointer" references, are only
needed when the object is used polymorphically, so do not require vtables. I
am rather dismayed, that you would make statements like "looks like" when
the code is readily available for inspection.

> > 3) saying that class C implements interface I should not be an implicit
> > agreement to make those function virtual.
>
> Maybe. But what's the harm in making them virtual?

The same reason not all member functions are virtual by default. It comes at
a price.

> If there is a
> serious potential problem with such functions being virtual, it looks to
> me like a proposal to add "final" to the language would be more
> appropriate. It would be more general than interfaces, which for the
> most part allow you to do what you can already do with ABCs (minus the
> non-virtual part).

Adding final to the language is not a bad proposal in of itself, but would
be a poor approximation of interfaces, as an interface is a well known and
understood concept that deserves its own construct.

---

Matthew Collett

unread,
Apr 24, 2004, 5:13:03 AM4/24/04
to
In article <JB1ic.20947$HF5.5...@wagner.videotron.net>,

cdig...@videotron.ca ("christopher diggins") wrote:

> > I don't understand how you can call an extra vtable pointer a linear
> > increase in object size.
>

> An extra vtable pointer is typically (for most C++ compilers) added to an
> object for each virtual base. That is why I said linear.

^^^^^^^

A "pure" ABC (i.e. a C++ class corresponding to a Java interface) has no
data, so there is no need to use virtual inheritance.

Best wishes,
Matthew Collett

--
Those who assert that the mathematical sciences have nothing to say
about the good or the beautiful are mistaken. -- Aristotle

---

christopher diggins

unread,
Apr 25, 2004, 9:38:05 PM4/25/04
to
"llewelly" <llewe...@xmission.dot.com> wrote in message
news:86y8opi...@Zorthluthik.local.bar...

> cdig...@videotron.ca ("christopher diggins") writes:
>
> [snip]
> > Signatures are very similar, and I note that in my most recent proposal
> > (http://www.heron-language.com/cpp-iop.html )
> [snip]
>
> I'm sorry, I don't see any mention of signatures on that web
> page. Maybe you forgot to update it?

My mistake, I confused an earlier post with my web page.

---

christopher diggins

unread,
Apr 25, 2004, 9:38:59 PM4/25/04
to
"Matthew Collett" <m.co...@auckland.ac.nz> wrote in message
news:m.collett-BF0EC...@lust.ihug.co.nz...

> In article <JB1ic.20947$HF5.5...@wagner.videotron.net>,
> cdig...@videotron.ca ("christopher diggins") wrote:
>
> > > I don't understand how you can call an extra vtable pointer a linear
> > > increase in object size.
> >
> > An extra vtable pointer is typically (for most C++ compilers) added to
an
> > object for each virtual base. That is why I said linear.
> ^^^^^^^
>
> A "pure" ABC (i.e. a C++ class corresponding to a Java interface) has no
> data, so there is no need to use virtual inheritance.


My error, I meant for each base with at least one virtual function.

---

David Abrahams

unread,
Apr 25, 2004, 9:53:05 PM4/25/04