Initialization in a constructor

  • Thread starter Massimiliano Alberti
  • Start date
M

Massimiliano Alberti

Now, in C++ you can do:

struct X
{
int ia;
int ib;
};

class CL
{
public:
X x1;
int a, b;

// you can do this
CL() : a(0), b(0)
{
}

// and you can do this
void DoSomething()
{
X xx = {0}; // it's equivalent to a memset(&xx, 0, sizeof(X));
}
};

Now... How can I zero x1 in the CL constructor?
And... Why the X xx = {0} works? It seems a strange syntax...

--- bye
 
T

Thomas Matthews

Massimiliano said:
Now, in C++ you can do:

struct X
{
int ia;
int ib;
};

class CL
{
public:
X x1;
int a, b;

// you can do this
CL() : a(0), b(0)
{
}

// and you can do this
void DoSomething()
{
X xx = {0}; // it's equivalent to a memset(&xx, 0, sizeof(X));
}
};

Now... How can I zero x1 in the CL constructor?

If you provide a default constructor for struct X:
struct X
{
int ia;
int ib;

X() : ia(0), ib(0) { ; }
};

Now when you declare an instance of struct X, it
will automatically initialize.
void DoSomething()
{
X xx; // Calls the constructor of struct X.
cout << "x.ia = " << x.ia << endl;
return;
}


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
R

Rob Williscroft

Massimiliano Alberti wrote in
Now, in C++ you can do:

struct X
{
int ia;
int ib;
};

class CL
{
public:
X x1;
int a, b;

// you can do this
CL() : a(0), b(0)

Add the follwing:

, x1()
{
}

// and you can do this
void DoSomething()
{
X xx = {0}; // it's equivalent to a memset(&xx, 0, sizeof(X));

Not really see below
}
};

Now... How can I zero x1 in the CL constructor?

See above, though since x1 comes before a and b you may want to
put it before a(0). i.e. CL() : x1(), a(0), b(0) {}.

This causes value initialization, which in this case
initializes x1's members to 0.

Note: Don't be tempted to start writing:

void f()
{
X x(); /* Whoopse, its a function declaration!, though */
X xx = X(); /* is Ok. */
}
And... Why the X xx = {0} works? It seems a strange syntax...

Its a shortend form of an aggragate initializer:

X xx = { 1, 2 };

Will initialize xx's members to 1 and 2 respectivly, if you stop
before you've initialized all members the remainder are default
initialized, either there default constructor is called, or in
the case of inbults (int etc) they are initialized with 0.

Note that X xx = {}; will work just as well in this case.

HTH.

Rob.
 
M

Massimiliano Alberti

See above, though since x1 comes before a and b you may want to
put it before a(0). i.e. CL() : x1(), a(0), b(0) {}.
Why? Is it to help the optimizer? (the compiler will more easily see that
I'm zeroing a contigous area of memory and optimize it)

--- bye
 
R

Rob Williscroft

Massimiliano Alberti wrote in
Why? Is it to help the optimizer? (the compiler will more easily see
that I'm zeroing a contigous area of memory and optimize it)

No the compiler will intialize members in declaration order,
and some compilers (g++) will warn you that the order you specify
in the initializer list *isn't* the order in which the initialization
is done.

#include <iostream>
#include <ostream>
#include <iomanip>

struct X
{
int a, b;

X() : b( 10 ), a( b ) {}
};


int main()
{
using namespace std;
cerr << X().a << '\n';
}

Of the 5 comilers I tried this on only 1 printed 10, 2 (both versions
of g++) warned about the "order problem", 4 of the compilers I
consider to be "highly" Standard conforming (including the one that
printed 10).

It's certainly the case that you can't reorder the initialization
of base classes, but that doesn't apply here, so it may be that
the 1 compiler (CBuilderX (preview)) that printed 10 is correct (i.e.
Standard conforming (*)). But from a practical point of view, we
should put initializers in declaration order for consistant portable
results.

Note (*) If I ever *need* to do an out of order initialization I
might check the Standard, I currently don't care as 25% of compilers
isn't portable, Standard conforming or not.

Rob.
 
A

Andrey Tarasevich

Massimiliano said:
...
X xx = {0}; // it's equivalent to a memset(&xx, 0, sizeof(X));
...

No, it is not.

The only types in C++ which can be predictably zeroed by using
'memset(.., 0, ..)' are 'char', 'signed char' and 'unsigned char' (and
aggregates built from these types). If you steamroll over an object of
any other type with 'memset(.., 0, ..)' you'll simply end up with an
object filled with "all-zeroes" bit-pattern, which does not necessarily
represents a "zero" value of that type. Moreover, it will not
necessarily be a valid object of that type at all.

In your case you are trying to zero-initialize 'int' objects with
'memset(.., 0, ..)'. This is not guaranteed to work in C++, even though
in most cases it works in practice.
 

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
474,161
Messages
2,570,892
Members
47,430
Latest member
7dog123

Latest Threads

Top