This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: dynamic_cast (bug 3(?))
- To: carlo at runaway dot xs4all dot nl
- Subject: Re: dynamic_cast (bug 3(?))
- From: "Martin v. Loewis" <martin at mira dot isdn dot cs dot tu-berlin dot de>
- Date: Sun, 21 Nov 1999 19:28:17 +0100
- CC: gcc at egcs dot cygnus dot com
- References: <19991115161247.A3646@xs4all.nl>
> I think that you have explained "v shall be an rvalue of a pointer
> to complete class type" as "if v has a virtual table (pointer), that
> pointer shall not be 0".
Well, no. A complete type is one that has been defined, not only
declared. A class type is either a struct or a class.
> (gdb) p *os
> $1 = {<ios> = {<_ios_fields> = {_strbuf = 0x40050640, _tie = 0x8049c38,
> _width = 0, _flags = 8209, _fill = 32, _state = 0 '\000',
> _exceptions = 0 '\000', _precision = 6, _arrays = 0x0}, _vptr. = 0x0},
> _vb.ios = 0x8049bfc}
>
>
> Note that the _vptr. is 0x0.
>
> Is this a bug in gcc? (ie, should you test if _vptr. is 0x0?), or
> is there something seriously wrong with `cerr'?
It is an error in cerr. Even though it is supposed to implement an
ostream, it does not have a virtual table. That is normally not a
problem, since ostream has only one (non-artificial) virtual function:
the destructor, which cannot be called for cout.
In your case, you manage to access the vtable of cerr, which is
constructed via
OSTREAM_DEF(cerr, CERR_SBUF,(ostream*)&cout, ios::unitbuf, )
in libio/stdstreams.cc. This, in turn, expands to
_fake_ostream cerr = { {& cerr .base}, {(streambuf*)& _IO_2_1_stderr_ , (ostream*)&cout , 0, ios::skipws|ios::dec| ios::unitbuf , ' ',0,0,6 }};
If you count fields, you'll find that this is sufficient to initialize
_ios_fields, but not ios (which only has the vtable as extra field).
If you want to fix this, it would probably best to put the vtable of
ostream (i.e. __vt_7ostream.3ios) into the vtable of cout and
cerr. You'd also need to change _fake_ostream to actually contain a
vtable field, instead of filler.
Regards,
Martin