deriving from a C struct

M

Mosfet

Hi,

I would like more info about deriving from an existing C struct.
Let's say I am fed up with always writing the same code shown below :



MYSTRUCT foo;
memset( &foo, 0, sizeof(MYSTRUCT) );
foo.cbSize = sizeof(MYSTRUCT);
SendMessage(xxx, WM_MYSTRUTC, &(foo), 0);

So I would like to do something like


struct MYSTRUCT_Helper : public MYSTRUCT
{
MYSTRUCT_Helper()
{
memset( this, 0, sizeof(MYSTRUCT) );
this->foo.cbSize = sizeof(MYSTRUCT);

}
}

and after

MYSTRUCT_Helper betterFoo;
SendMessage(xxx, WM_MYSTRUTC, &(betterFoo), 0);




Can I do something like that ?
 
M

Mosfet

Mosfet a écrit :
Hi,

I would like more info about deriving from an existing C struct.
Let's say I am fed up with always writing the same code shown below :



MYSTRUCT foo;
memset( &foo, 0, sizeof(MYSTRUCT) );
foo.cbSize = sizeof(MYSTRUCT);
SendMessage(xxx, WM_MYSTRUTC, &(foo), 0);

So I would like to do something like


struct MYSTRUCT_Helper : public MYSTRUCT
{
MYSTRUCT_Helper()
{
memset( this, 0, sizeof(MYSTRUCT) );
this->foo.cbSize = sizeof(MYSTRUCT);

}
}

and after

MYSTRUCT_Helper betterFoo;
SendMessage(xxx, WM_MYSTRUTC, &(betterFoo), 0);




Can I do something like that ?

and if I add a method inside will it still work ?
 
V

Victor Bazarov

Mosfet said:
Mosfet a écrit :

Bad idea in C++, in general. Better to drop that habit. It is much
better to explicitly initialise your aggregate:

MYSTRUCT foo = {};

Whatever that does...

'public' is superfluous. OK for a reminder, though.

You can, but it's a BAD IDEA(tm) to memset the object (or any of
its parts) to 0, especially in its own constructor.
and if I add a method inside will it still work ?

Yes, I suppose it will work.

V
 
J

JohnQ

You can, but it's a BAD IDEA(tm) to memset the object (or any of
its parts) to 0, especially in its own constructor.

You mean, as opposed to using an initializer list or setting the members to
zero explicitly inside the constructor, right? IOW, you have issue with the
memset and not the zeroing (?).

John
 
B

Bo Persson

JohnQ wrote:
:: ::
::: You can, but it's a BAD IDEA(tm) to memset the object (or any of
::: its parts) to 0, especially in its own constructor.
::
:: You mean, as opposed to using an initializer list or setting the
:: members to zero explicitly inside the constructor, right? IOW, you
:: have issue with the memset and not the zeroing (?).
::

Yes. By definition, you cannot memset the object in a constructor.

Memset only works for POD objects, and PODs don't have constructors.



Bo Persson
 
V

Victor Bazarov

JohnQ said:
You mean, as opposed to using an initializer list or setting the
members to zero explicitly inside the constructor, right? IOW, you
have issue with the memset and not the zeroing (?).

Zeroings differ. 'memset' with 0 does a different zeroing than
initialising with 0. For example, it is not guaranteed that a null
pointer has "all bits zero" internal representation. There can be
a floating point representation with 0.0 represented differently
than "all bits zero", as well.

What I am advocating is zero-initialisation, as opposed to setting
all bytes to 0 using whatever means available ('memset' included).

V
 
O

Old Wolf

Hi,

I would like more info about deriving from an existing C struct.
Let's say I am fed up with always writing the same code shown below :

MYSTRUCT foo;
memset( &foo, 0, sizeof(MYSTRUCT) );

A good start would be to write better code:
MYSTRUCT foo = { 0 };

instead of the above 2 lines.
foo.cbSize = sizeof(MYSTRUCT);

foo.cbSize = sizeof foo;
SendMessage(xxx, WM_MYSTRUTC, &(foo), 0);

Why the superfluous brackets?
So I would like to do something like

struct MYSTRUCT_Helper : public MYSTRUCT
{
MYSTRUCT_Helper()
{
memset( this, 0, sizeof(MYSTRUCT) );

I suspect this line would cause trouble, luckily it
is not necessary!
this->foo.cbSize = sizeof(MYSTRUCT);

what is 'foo' here?

Indenting is your friend...
and after

MYSTRUCT_Helper betterFoo;
SendMessage(xxx, WM_MYSTRUTC, &(betterFoo), 0);

Can I do something like that ?

Try this, assuming you can't change the definition
of MYSTRUCT:

struct MYSTRUCT_Helper : public MYSTRUCT
{
MYSTRUCT_Helper(): MYSTRUCT()
{
cbSize = sizeof(MYSTRUCT);
}
MYSTRUCT * operator&() { return this; }
};
 
J

John Harrison

Mosfet said:
Hi,

I would like more info about deriving from an existing C struct.
Let's say I am fed up with always writing the same code shown below :



MYSTRUCT foo;
memset( &foo, 0, sizeof(MYSTRUCT) );
foo.cbSize = sizeof(MYSTRUCT);
SendMessage(xxx, WM_MYSTRUTC, &(foo), 0);

So I would like to do something like


struct MYSTRUCT_Helper : public MYSTRUCT
{
MYSTRUCT_Helper()
{
memset( this, 0, sizeof(MYSTRUCT) );
this->foo.cbSize = sizeof(MYSTRUCT);

}
}

and after

MYSTRUCT_Helper betterFoo;
SendMessage(xxx, WM_MYSTRUTC, &(betterFoo), 0);




Can I do something like that ?

You can, but it would be better design to write a wrapper for your stuct
not derive from it.

class MYSTRUCT_Helper
{
public:
MYSTRUCT_Helper()
{
memset(&mys, 0, sizeof mys);
mys.cbSize = sizeof mys;
}
void send_message(xxx)
{
SendMessage(xxx, WM_MYSTRUTC, &mys, 0);
}
private:
MYSTRUCT mys;
};

john
 
P

peter koch

I would like more info about deriving from an existing C struct.
Let's say I am fed up with always writing the same code shown below :
MYSTRUCT foo;
memset( &foo, 0, sizeof(MYSTRUCT) );
[snip]
Try this, assuming you can't change the definition
of MYSTRUCT:

struct MYSTRUCT_Helper : public MYSTRUCT
{
MYSTRUCT_Helper(): MYSTRUCT()
{
cbSize = sizeof(MYSTRUCT);
}
MYSTRUCT * operator&() { return this; }
Why overload operator&? It seems to me that you were perhaps
contemplating another solution, having MYSTRUCT a member of
MYSTRUCT_Helper?

/Peter
[snip]
 
V

Victor Bazarov

John said:
You can, but it would be better design to write a wrapper for your
stuct not derive from it.

class MYSTRUCT_Helper
{
public:
MYSTRUCT_Helper()
{
memset(&mys, 0, sizeof mys);
mys.cbSize = sizeof mys;
}

I'd still probably relied on a normal default-initialisation instead
of 'memset':

MYSTRUCT_Helper() : mys()
{
mys.cbSize = sizeof mys;
}
void send_message(xxx)
{
SendMessage(xxx, WM_MYSTRUTC, &mys, 0);
}
private:
MYSTRUCT mys;
};

john

V
 
E

ed

Mosfet said:
Hi,

I would like more info about deriving from an existing C struct.
Let's say I am fed up with always writing the same code shown below :

<SNIP>

First, I believe that something like what you wrote will work. I read a
few of the responses you received and would like to straighten a few
things out:

1. There's absolutely no difference between a struct and a class other
than that all members of a class are by default private while all
members of a struct are by default public. So anything you can do to a
class you can do to a struct.

2. You received some feedback about memsetting the whole class/struct
not being a good idea. In general, this is true - for two reasons. The
first is that your struct/class may have non-primitive data members. For
example, memsetting an std::string to 0 might be a bad idea. The second
is that as soon as your struct/class has a virtual member function, the
sizeof the vtable pointer is added to the sizeof your struct. So if you
memset the sizeof the struct, you will clobber the vtabl pointer with
zero. This can't possibly be good ;)

However, since you're already in the memsetting business one way or
another, doing it from inside a call to your constructor isn't any
worse. Someone mentioned that you shouldn't be able to memset 'this'
from inside the constructor, but I see absolutely no reason why this
should be so. It's not true.

3. Anyway, why do you need to extend the existing structure at all?
Assuming you own its definition, you can just add a constructor to the
existing struct. Then you can actually remove the existing memsets from
your code! Since adding the constructor (or any other non-virtual
function member) to a struct/class does not change its sizeof, you will
even remain binary-compatible with any other code using this struct.

The above is even possible if the header defining the struct is used by
both C and C++ code, although you'll have to #ifdef your constructor :)

Hope this helps!
-Ed
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,241
Latest member
Lisa1997

Latest Threads

Top