Thread View: comp.lang.c++.moderated
3 messages
3 total messages
Started by Rodrigo de Salvo Braz
Mon, 15 Apr 1996 17:19
I don't believe it! Weird thing about Virtual tables
Author: Rodrigo de Salvo Braz
Date: Mon, 15 Apr 1996 17:19
Date: Mon, 15 Apr 1996 17:19
31 lines
1560 bytes
1560 bytes
Debugging a project in Borland C++ 4.0, I noticed something
unexpected...
The virtual table of one of my classes (say, Dog) is initialized by
code!
It sounds ok at first, but since each module has its own initializing
code (for global variables and similar stuff), I have Dog's virtual
table initialized AFTER initializing code of modules located BEFORE
Dog's module in the Project definition. Since I have variables using
Dog in those earlier modules, I get a real crash!
So I have to worry about the modules definition order in the project
in order to have my program working properly, and that sounds really
odd!
Am doing any mistake on it? Is there any option preventing it? Why
doesn't the compiler create the virtual tables already initialized?
Cheers,
Rodrigo Braz
[ Articles to moderate: mailto:c++-submit@netlab.cs.rpi.edu ]
[ Read the C++ FAQ: http://www.connobj.com/cpp/cppfaq.htm ]
[ Moderation policy: http://www.connobj.com/cpp/guide.htm ]
[ Comments? mailto:c++-request@netlab.cs.rpi.edu ]
Re: I don't believe it! Weird thing about Virtual tables
Author: Dietmar Kuehl
Date: Tue, 16 Apr 1996 15:35
Date: Tue, 16 Apr 1996 15:35
90 lines
4366 bytes
4366 bytes
Hi,
Rodrigo de Salvo Braz (braz@ime.usp.br) wrote:
: Debugging a project in Borland C++ 4.0, I noticed something
: unexpected...
: The virtual table of one of my classes (say, Dog) is initialized by
: code!
This is a reasonable thing to do: Remember that the virtual functions
used may change in the process of constructing an object of a derived
class. Consider e.g. this simple example:
#include <iostream.h>
class A
{
public:
virtual char const *f() { return "A::f()"; }
A() { cout << "A::A(): " << f() << endl; }
~A() { cout << "A::~A(): " << f() << endl; }
};
class B: public A
{
public:
virtual char const *f() { return "B::f()"; }
B() { cout << "B::B(): " << f() << endl; }
~B() { cout << "B::~B(): " << f() << endl; }
};
int main() { B b; return 0; }
The output of this simple program is
A::A(): A::f()
B::B(): B::f()
B::~B(): B::f()
A::~A(): A::f()
This just demonstrates the rule that the call to a virtual function
from a constructor or a destructor uses a static function lookup. To
implement this easily, it is reasonable to initialize the virtual
function table with the relevant table of the base class before the
base class constructor is called. Then this virtual function table is
replaced by the virtual function table for the derived class before the
derived class constructor is called. Likewise for the destructor.
: It sounds ok at first, but since each module has its own initializing
: code (for global variables and similar stuff), I have Dog's virtual
: table initialized AFTER initializing code of modules located BEFORE
: Dog's module in the Project definition. Since I have variables using
: Dog in those earlier modules, I get a real crash!
The real problem is not that the virtual function table is not
initialized but that your object is used before it is constructed:
Since C++ provides no mechanism to define the order of construction
(and destruction) of global objects, you should avoid using them, at
least if some of your objects depend on others to be constructed when
they are constructed themselves (or, in the reverse, that the objects
are not yet destructed when they are destructed themselves). You can
avoid this problem (for the construction of the objects) by wrapping
the necessary global objects into functions like this:
T &global_T() { static T object(/*...*/); return object; }
: So I have to worry about the modules definition order in the project
: in order to have my program working properly, and that sounds really
: odd!
Yes, this is odd because you rely on a very system dependent mechanism
instead of removing the problem.
: Am doing any mistake on it? Is there any option preventing it? Why
: doesn't the compiler create the virtual tables already initialized?
See above. Although the compiler can use a different mechanism to
ensure that the virtual functions depend on the static type in the
constructor and the destructor, there is no requirement to do so: Using
a non-static member function on an object before construction begins,
results in undefined behavior anyway (12.7 [class.cdtor] of the DWP).
This is what you are attempting and what you get: undefined behavior.
- --
dietmar.kuehl@uni-konstanz.de
http://www.informatik.uni-konstanz.de/~kuehl/
I am a realistic optimist - that's why I appear to be slightly pessimistic
[ Articles to moderate: mailto:c++-submit@netlab.cs.rpi.edu ]
[ Read the C++ FAQ: http://www.connobj.com/cpp/cppfaq.htm ]
[ Moderation policy: http://www.connobj.com/cpp/guide.htm ]
[ Comments? mailto:c++-request@netlab.cs.rpi.edu ]
Re: I don't believe it! Weird thing about Virtual tables
Author: Rob Stewart
Date: Wed, 17 Apr 1996 23:12
Date: Wed, 17 Apr 1996 23:12
31 lines
1933 bytes
1933 bytes
Rodrigo de Salvo Braz wrote:
[snip]
> The virtual table of one of my classes (say, Dog) is initialized by
> code!
>
> It sounds ok at first, but since each module has its own initializing
> code (for global variables and similar stuff), I have Dog's virtual
> table initialized AFTER initializing code of modules located BEFORE
> Dog's module in the Project definition. Since I have variables using
> Dog in those earlier modules, I get a real crash![snip]
> Am doing any mistake on it? Is there any option preventing it? Why
> doesn't the compiler create the virtual tables already initialized?
>
It sounds as though you are using static Dogs. Since the
initialization order of statics are not guaranteed, the static
Dogs used in your other translation units may not be initialized
by the time you use them.
One workaround for this is to declare the static Dogs in the
function where they're needed, or to declare them in a function
that can then provide them to the others.
--
Rob Stewart | My opinions are generally my own. They do
Datalytics, Inc.| not necessarily reflect those of my employer.
[ Articles to moderate: mailto:c++-submit@netlab.cs.rpi.edu ]
[ Read the C++ FAQ: http://www.connobj.com/cpp/cppfaq.htm ]
[ Moderation policy: http://www.connobj.com/cpp/guide.htm ]
[ Comments? mailto:c++-request@netlab.cs.rpi.edu ]
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads