Topic: Clearing base struct in a derived class.


Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/01/14
Raw View
het@pangea.ca (Harvey Taylor) writes:

>    With this sort of a hierarchy:
>
>    struct BaseStruct { /*nothing fancy */ };
>    class Derived : public BaseStruct { /* stuff */ };
>
>    is it safe and well-defined to do something like:
>
> void Derived::SomeFunction(void)
> {
>  BaseStruct * pBaseStruct = (BaseStruct *)this;
>  memset(pBaseStruct, 0, sizeof(BaseStruct));
>  // SomeOSCall(pBaseStruct);
> }

In general it is unsafe to zero out a class. You might
wind up zeroing out something the implementation put in
the class apart from your declared data members. For example,
you might overwrite a vtable pointer, after which you will
get mysterious program crashes.

If the base class is a POD struct (a struct which could be compiled
by a C compiler), it is likely to be safe to zero it out.

> The rationale for wanting to do this, is that I need
> to pass a C style pointer to a BaseStruct back to the
> OS and I want to make sure there is no garbage in any
> field.

The safest thing to do is to set each field to zero. Setting
a floating-point object or a pointer to zero is always
safe, and is not necessarily the same as using memset to zero
out the bytes. (The zero or null value might not be represented
as all-bits-zero.)

> I guess the question is are we guaranteed anything about
> the internal structure of Derived?

Except for a few trivial guarantees about increasing address
order between access specifiers within any one class, you can't
make any portable assumptions about class layout.

--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]