peter@mit-amt.MEDIA.MIT.EDU (Peter Schroeder) (01/11/90)
// I am running cfront 2.0 and have a problem with the +e[0|1] option.
// Is it a bug?
// this is `test.h'
// ***************************************
class base{
public:
virtual void foobar() = 0;
};
class derived : public base{
public:
derived() {}
void foobar() {}
};
// ***************************************
// this is `test.C'
// ***************************************
#include "test.h"
void
bla()
{
derived d;
}
// ***************************************
// If I compile `test.C' with the +e0 option I get (heavily edited)
extern struct __mptr* __ptbl__4base__test_C;
extern struct __mptr* __ptbl__7derived__test_C;
char bla__Fv ()
{
struct derived __1d ;
#line 6 "test.C"
( (( (( (((((struct base *)(& __1d )))|| (__nw__FUi ( sizeof (struct base)) ))?((((struct base *)(& __1d )))-> __vptr__4base = (struct
#line 6 "test.C"
__mptr *) __ptbl__4base__test_C):0 ), (((((struct base *)(& __1d )))))) ), ((& __1d )-> __vptr__4base = (struct __mptr *) __ptbl__7derived__test_C)) ), (((& __1d )))) ;
}
// the last mess is the inline constructor for derived. It makes a reference
// to the `extern struct __mptr* __ptbl__7derived__test_C', as well as
// `extern struct __mptr* __ptbl__4base__test_C' but these `struct*'
// are never defined in this file. This makes sense, since I used the +e0
// flag. But, I cannot ever hope to generate the actual definition of this
// `struct __mptr*' running +e1 on some other file because the
// filename of `test.C' is encoded in this `extern struct __mptr*'.
// Result: I get unresolved externals complaints from the linker, which
// I can only get to go away by compiling all files which include `test.h'
// with the +e1 option. The very thing I am trying to avoid.
// Interestingly enough changing base::foobar to plain virtual (from pure
// virtual) gives me this
extern struct __mptr __vtbl__4base[];
struct __mptr* __ptbl__4base__test_C = __vtbl__4base;
// so now I am only left with an unresolved external for the other one
// `__ptbl__7derived__test_C'. Better, but not good enough.
// What I generally do is that I compile all files in my system with +e0, but
// one special file (which I call `vtbl.C'), which only contains `#include's
// for all header files which have virtual functions. So far this never
// caused a problem. This is my first use of a pure virtual and that broke
// it.
//
// Am I missing something or have I stumbled upon a bug?
// Any clarification you can offer would be appreciated.
// Thank you
// Peter
// peter@media-lab.media.mit.edutom@elan.elan.com (Tom Smith) (01/16/90)
From article <1379@mit-amt.MEDIA.MIT.EDU>, by peter@mit-amt.MEDIA.MIT.EDU (Peter Schroeder): > // I am running cfront 2.0 and have a problem with the +e[0|1] option. > // Is it a bug? [ description of +e[0|1] argument behavior for optimizing virtual function table instance declarations ] > // What I generally do is that I compile all files in my system with +e0, but > // one special file (which I call `vtbl.C'), which only contains `#include's > // for all header files which have virtual functions. So far this never > // caused a problem. This is my first use of a pure virtual and that broke > // it. I once determined that in a 1.2M executable built with C++ 1.2 from Glockenspeil, over 100K was taken up by extraneous virtual function table instances. In that particular application, using the +e arguments was impractical because the product was a set of libraries; one could not determine until link-time which class definitions and table instances were required. I remember reading somewhere that the C++ 2.0 implementation was going to generate the virtual function table for a given class in the file that implemented the first virtual member function for that class, and all other files would be external declarations. Checking out the generated C from my copy of C++ 2.0 from Sun, this does not appear to be the case. What ever happened to this plan? Thomas Smith Elan Computer Group, Inc. tom@elan.com, ...!{ames, uunet, hplabs}!elan!tom
roger@decvax.UUCP (Roger H. Scott) (01/20/90)
A lot of work has gone into 2.0 cfront to reduce or eliminate redundant vtbls. Unless you are doing something *very* strange, it is quite likely that playing silly games with +e options [one of the biggest crocks to come along in a long time] will not buy you anything under 2.0. The only caveat is to make sure that each class that adds or redefines a virtual function defines at least one of those functions *non*-inline. I suggest you try building your whole system without any +e use and see how you like the result.