C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

zero initialize a large amount of class members
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
marcel.lanz@gmail.com
Guest





PostPosted: Thu Sep 15, 2005 11:00 pm    Post subject: zero initialize a large amount of class members Reply with quote



I have to use a class with a lot of members.
Most of them are "int" or "bool" or just PODs.

I think for one who has to maintain such a class with 100+ members, one
will forget one of the members to initialize in the initializer list in
a ctor.

How can this be done in a better way ?

what I tried:

// 1st try
class B {
public: int a; std::string s; int c;
};
B b = { 0 }; // works if members are all POD. aborts() here

// 2nd try
class B {
public: int a; std::string s; int c; ... a lot more of them (at least
100)
static B zero;
};
B B::zero;
B b = B::zero; // statics are zero initialized, yep

// 3rd try
class B {
public: int a; std::string s; int c;
B():a(0),c(0) {} // with 100 of them, my maintainers will miss one,
I'm sure.
};

// 4rd try
class B {
public:
struct PODs { int a; int c; }; // again, +100
struct NonPODs { std::string s; }; // some of them
PODs pods;
NonPODS non_pods;

B(){ PODs p = {0}; pods = p; }; // tried B():pods({0}){}
};

well the last is somehow suboptimal since one has to know the type of a
member.

- How should it be done ?
- Why can't members be default initialized in declaration
class B { public: int a=0; std::string s; int c=0; }
here no one would miss a member in the initialization list of a ctor.


Marcel


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Yuri Khan
Guest





PostPosted: Fri Sep 16, 2005 8:13 am    Post subject: Re: zero initialize a large amount of class members Reply with quote



[email]marcel.lanz (AT) gmail (DOT) com[/email] wrote:

Quote:
I have to use a class with a lot of members.
Most of them are "int" or "bool" or just PODs.

I think for one who has to maintain such a class with 100+ members, one
will forget one of the members to initialize in the initializer list in
a ctor.

How can this be done in a better way ?

Your problem is that you have way too many members. I strongly suspect
that they can be factored into groups that correspond to more
finely-grained entities.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Rob
Guest





PostPosted: Fri Sep 16, 2005 8:15 am    Post subject: Re: zero initialize a large amount of class members Reply with quote



[email]marcel.lanz (AT) gmail (DOT) com[/email] wrote:

Quote:
I have to use a class with a lot of members.
Most of them are "int" or "bool" or just PODs.

I think for one who has to maintain such a class with 100+ members,
one will forget one of the members to initialize in the initializer
list in a ctor.

I would argue that, if you have a class with 100+ members, you can
probably do a bit of factoring. Group your members in some way
(probably based on relationships between them) into a set of classes
[or structs, and then assemble your monster class as a collection of
instances of those classes.

For example;

struct IntegersIWant
{
int a,b,c,d,e,f,g;
};

struct DoublesIWant
{
double p,q,r,s,t,u,v,w,x,y,z
};

class MyClass
{
DoublesIWant doubles;
IntegersIWant integers;
std::string str;
MyClass::MyClass()
{
// str will be initialised using it's default constructor
DoublesIWant x = {0};
doubles = x;
IntegersIWant i = {0};
integers = i;
};
};

If you (say) have a lot of integers, you could use the scheme
recursively. The key is building big things from somewhat smaller
things which are built from little things that are easy to construct so
the bits work correctly and can be put together.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
albrecht.fritzsche
Guest





PostPosted: Fri Sep 16, 2005 8:16 am    Post subject: Re: zero initialize a large amount of class members Reply with quote

[email]marcel.lanz (AT) gmail (DOT) com[/email] wrote:
Quote:
I have to use a class with a lot of members.
Most of them are "int" or "bool" or just PODs.

I think for one who has to maintain such a class with 100+ members, one
will forget one of the members to initialize in the initializer list in
a ctor.

How can this be done in a better way ?

Using tools like PClint.

Ali

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Matjaz Depolli
Guest





PostPosted: Fri Sep 16, 2005 8:46 am    Post subject: Re: zero initialize a large amount of class members Reply with quote

First of all, I think having 100+ members in a struct or a class is a
bad practice. I can not possibly imagine why someone would need classes
that large.

Leaving that aside, for PODs I believe = {0} initializer to be the
simplest solution. After you add some non PODs I'm not sure anymore.
The fact, that you need them all zero initialized, in my view shows
that you should rethink your design.

On your question of why can't members be initialized in declaration -
how would that fit with the multiple ctors?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Tony Delroy
Guest





PostPosted: Fri Sep 16, 2005 12:24 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote

Hi Marcel,

Your second try isn't too bad, if people remember to assign from the
static when their own object isn't also static.

You could also create a simple wrapper class for int, double etc that
adds the construction behaviour you want. First stab...

template <typename T>
class Zeroed
{
public:
Zeroed() : x_(0) { }
Zeroed(T x) : x_(x) { }

operator T&() { return x_; }
operator const T&() const { return x_; }

private:
T x_;
};

then

class B
{
public:
Zeroed<int> a;
std::string b;
Zeroed<double> c;
};

Use some typedefs if you think it's clearer/easier (I'm indifferent)...

typedef Zeroed<int> Int0; // hope you think of a better name...

Of course it breaks the usual guidelines about explicit constructors
and avoiding casting operators, with all the documented issues, which
usually aren't too problematic. You can make it all explicit, have a
get method etc. if you don't mind usage being affected.

A "heavyweight" solution, which isn't worth the hassle unless you deal
in doens of these classes, each with hundreds of members, is automated
code generation. At the hacky end, use a tool like ctags to pull out
the POD fields from your class definition and generate an
initialise_to_zero function from that metadata: perl might be an
appropriate tool. More properly, use an introspective preprocessing
system, OpenC++ is freely available, and my impression is that it would
be relatively easy to write a base meta-class that automatically
initialises data members of particular types to zero .

There's even the old memset - but then the maintainer needs to know to
keep the POD data members together in the class, and where to start and
end, which can change and needs maintaining. Error prone and not
recommended. More robustly, but with a performance hit, you could
adopt a pimpl-like mechanism using calloc to ensure 0-initialised data.

Cheers,

Tony


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
kanze
Guest





PostPosted: Fri Sep 16, 2005 12:25 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote

[email]marcel.lanz (AT) gmail (DOT) com[/email] wrote:
Quote:
I have to use a class with a lot of members.
Most of them are "int" or "bool" or just PODs.

I think for one who has to maintain such a class with 100+
members, one will forget one of the members to initialize in
the initializer list in a ctor.

How can this be done in a better way ?

what I tried:

// 1st try
class B {
public: int a; std::string s; int c;
};
B b = { 0 }; // works if members are all POD. aborts() here

Shouldn't. This is the correct way to do it.

Of course, you can use any values:

B b = { 5, "abc", 10 } ;

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
marcel.lanz@gmail.com
Guest





PostPosted: Fri Sep 16, 2005 12:37 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote

Thanks for far for the answers. Some of you say that +100 members is
"bad design". I agree on that.
The struct I use is part of a legacy old system, at the moment I have
no choice.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Andrew Koenig
Guest





PostPosted: Fri Sep 16, 2005 3:54 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote

<marcel.lanz (AT) gmail (DOT) com> wrote


Quote:
I have to use a class with a lot of members.
Most of them are "int" or "bool" or just PODs.

I think for one who has to maintain such a class with 100+ members, one
will forget one of the members to initialize in the initializer list in
a ctor.

How can this be done in a better way ?

How about putting all the members you want to initialize in an inner
structure and value-initialize it?

That is:

class Large {
struct Initialized {
int a;
int b;
// and so on
} m;

Large(): m(Initialized()) { /* ... */ }

};

Now if you add a new member to struct Initialized, it will automatically
start out as zero.

Of course, you will have to refer to this->m.a instead of this->a, but
that's not a big hassle.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Walter Bright
Guest





PostPosted: Sat Sep 17, 2005 1:59 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote


<marcel.lanz (AT) gmail (DOT) com> wrote

Quote:
- How should it be done ?

A couple ways come to mind:

1) Overload operator new() for the class, and have that implementation of
new() zero out the memory. Of course, this will only have an effect for
new'd allocations, not stack allocations.

2) Create a global static instance of your class, as in:

B bzero;

this will default initialize to all 0 all members. Then, as the first line
in your constructor:

*this = bzero;

This won't work if there are virtual functions and if class C derives from B
and overrides any virtual functions. It won't work if any members need to be
member-initialized by the default constructor to anything but 0. If you use
memset(this, 0, sizeof(B)), that won't work if there are any virtual
functions.

There isn't any easy answer to this for C++. I know I've been bitten by this
particular problem several times, and wasted lots of time tracking the
problem down. That's why, in the D programming language, all members get
default initialized.

-Walter
www.digitalmars.com C, C++, D compilers
"code of the nerds"



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Gabriel Dos Reis
Guest





PostPosted: Sat Sep 17, 2005 2:00 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote

"Andrew Koenig" <ark (AT) acm (DOT) org> writes:

Quote:
marcel.lanz (AT) gmail (DOT) com> wrote in message
news:1126795481.692658.75960 (AT) z14g2000cwz (DOT) googlegroups.com...

I have to use a class with a lot of members.
Most of them are "int" or "bool" or just PODs.

I think for one who has to maintain such a class with 100+ members, one
will forget one of the members to initialize in the initializer list in
a ctor.

How can this be done in a better way ?

How about putting all the members you want to initialize in an inner
structure and value-initialize it?

That is:

class Large {
struct Initialized {
int a;
int b;
// and so on
} m;

Large(): m(Initialized()) { /* ... */ }

};

Now if you add a new member to struct Initialized, it will automatically
start out as zero.

Of course, you will have to refer to this->m.a instead of this->a, but
that's not a big hassle.

Would not

struct Initialized {
// ...
};

struct Large : private Initialized {
Large() : Initialize() { }
// ...
};

also trigger value-initialization?

--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Dave Harris
Guest





PostPosted: Sun Sep 18, 2005 1:34 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote

[email]marcel.lanz (AT) gmail (DOT) com[/email] () wrote (abridged):
Quote:
I think for one who has to maintain such a class with 100+ members, one
will forget one of the members to initialize in the initializer list in
a ctor.

How can this be done in a better way ?

This probably won't help you, but sometimes it's possible to organise them
into arrays.

class B {
enum { a, c, ..., end_ints };
int ints[end_ints];
};

then instead of
++b.c;

you'd use:
++b.ints[B::c];

It's now easy to write loops to initialise them, and to generally treat
them in a uniform way. The occasions I've had large numbers of variables,
I needed the uniform infrastructure anyway. (I used more templates, and
named and exploited the enum type more.)

-- Dave Harris, Nottingham, UK.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
CodeCracker
Guest





PostPosted: Sun Sep 18, 2005 5:38 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote

1. Use a function like InitializeAll() in your class which should be
private and called by all your various ctors where this will be
required. In that create an array of void pointers consisting of the
address of each of your member variables. Loop over them and assign
zero value to them according to there type using RTTI.
2. Instead of using int, double etc. use a class for each Int, Doubles
etc and in that initialize the value of each to zero depending on there
type in the default constructor.

One is a joke but another should work. Though the second one is clumsy
to start with, once the things are in place it will be easy to add more
member variables without any thought to initialize them


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Graeme Prentice
Guest





PostPosted: Sun Sep 18, 2005 5:51 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote

On 17 Sep 2005 09:59:30 -0400, Walter Bright wrote:

Quote:

[email]marcel.lanz (AT) gmail (DOT) com[/email]> wrote in message
news:1126795481.692658.75960 (AT) z14g2000cwz (DOT) googlegroups.com...
- How should it be done ?

A couple ways come to mind:

1) Overload operator new() for the class, and have that implementation of
new() zero out the memory. Of course, this will only have an effect for
new'd allocations, not stack allocations.

Writing binary zero to memory isn't the same thing as
zero-initialization, but it might be a compromise you're willing to live
with as it works on most platforms.


Quote:

2) Create a global static instance of your class, as in:

B bzero;

this will default initialize to all 0 all members.


Actually it will first zero initialize the object, then it will default
initialize it - which means default construction for a non POD such as
this. Default construction will leave POD members uninitialized if not
explicitly initialized, but zero-initialization sets all scalar
sub-objects to zero.

Quote:
Then, as the first line
in your constructor:

*this = bzero;

This is the most dependable solution as value initialization is not
supported correctly on some compilers.


Quote:

This won't work if there are virtual functions and if class C derives from B
and overrides any virtual functions.

Why not?

It won't work if the class has any non-static reference members or
non-static const members.


Quote:
It won't work if any members need to be
member-initialized by the default constructor to anything but 0.

Yes it will. The default constructor for bzero will be called after
zero-initialization so it can assign any special values it wants.

Quote:
If you use
memset(this, 0, sizeof(B)), that won't work if there are any virtual
functions.

This is a bad idea.


Quote:

There isn't any easy answer to this for C++. I know I've been bitten by this
particular problem several times, and wasted lots of time tracking the
problem down. That's why, in the D programming language, all members get
default initialized.

This is fine for D but for C++ the overhead is too great when the
initialization isn't wanted - especially in embedded systems, which is
why C++ gives the programmer the choice.


Interesting how the static a1 object gets copied onto itself in the
default constructor in this code.

#include <iostream>
#include <ostream>
#include <string>

struct s1
{
int d1;
int d2;
int d3;
std::string b;
virtual void f1(){}
s1() { static s1 a1; *this = a1;
std::cout << "n* " << d1; d1 = 53; }
};

struct s2 : s1
{
void f1(){ std::cout << "n$ "
<< d1 << ' ' << b << ' ';}
};

int main()
{
s1 a1;
s2 a2;
a2.f1();
(&a1)->f1();
}

Graeme

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Andrei Alexandrescu (See
Guest





PostPosted: Sun Sep 18, 2005 5:53 pm    Post subject: Re: zero initialize a large amount of class members Reply with quote

Walter Bright wrote:
Quote:
There isn't any easy answer to this for C++. I know I've been bitten by this
particular problem several times, and wasted lots of time tracking the
problem down. That's why, in the D programming language, all members get
default initialized.

I think a better spec is to guarantee that all members have meaningful
values when read... see the difference? Surprised)

That would work great for C++, too.


Andrei

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.