In article <8vfejv$jfg$1@inn.qnx.com>,
Dave Lees <dave40@@rochester.rr.com> wrote:
Mario Charest <mcharest@void_zinformatic.com> wrote in message
news:8vf59e$grn$> 1@nntp.qnx.com> …
And remember that sizeof is handled at compile time not runtime.
That’s the whole point, in this case it’s not >
> That is what
the compiler is warning me about. It’s telling me the size information
is store within the class, thus it can be mistakenly erased.
You mentioned in your other message it is hard-coded in the assembly, thus
was at least in this case, generated at compile.
I don’t think its trying to tell you size information is stored in the
class, its telling you “compiler-generated information” (i.e. the vtable) is
stored in the memory for the object. It is warning you not to clear with
memset or anything similar, or you will destroy the vtable and blow up your
next virtual method call.
Bingo! The compiler will always know the correct sizeof since you can only
do it on a complete type definition, so it will know the size of the
vtable generated. The issue is that the warning notifies the programmer
to be wary of memset and its ilk.
As far as syntax goes, I don’t know enough about internals of vtables, but I
would fear that
n*sizeof(T) might not even equal
sizeof(T[n]) in every case.
Wouldn’t the function pointers be the same for each member of the array,
with only the hidden “this” parameter changing, and thus be subject to
optimization by storing only once?
Well, it would be compiler dependent. I’m not sure if an optimization
promoting the vtable to the array itself would be legal – presumably not –
but I doubt if such an optimization would be practical in any case.
The reason I don’t think it would be legal is that it could only be
possible if you had a notion of “final” classes, such as Java has.
Otherwise, the array is still polymorphic – any element could be a
sub-class if T is a pointer. In such a case, each element could have a
different vtable. (Thinking about it further, if the array were determined
not to be pointers, the compiler could do something, but only for that
highly specific case).
I would be careful to use the one you actually mean.
Which means that for operator new(), you really do have to use sizeof
to obtain enough memory for the vtable. Can you do a sizeof(T[n])
in C++ – where n is not a constant? I remember C++ sizeof() to be a little
more flexible – allowing type declarations in the expression – but I
don’t know if it goes that far. That would make sizeof(T[n]) the correct
thing to do. Otherwise, you have no choice but to do sizeof(T)*n,
because T might be a pointer.
By the way, location of the vtable is a damned-if-you-do-damned-
if-you-don’t sort of issue. If the vtable is at the start of the
object, you can easily trash it with reinterpret casts; if it’s at the
end of an object with an array at the end, you can easily trash it
if you don’t do correct bounds checking. I experienced the latter
in looking at horrible C++ device code that got plopped on our doorstep.
(Watcom puts the vtable at the end). I would lean towards the former,
because it’s a little more obvious when it happens.
=Dave
–
Steve Furr email: furr@qnx.com
QNX Software Systems, Ltd.