Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Default constructor weirdness in member initialization list

Reply
Thread Tools

Default constructor weirdness in member initialization list

 
 
mhvaughn@gmail.com
Guest
Posts: n/a
 
      02-01-2008
struct S1
{
int i;
};

struct S2 {
S1 s;
// version 1
S2() {} ;
// version 2
S2() : s() {} ;
};

int main()
{
S2 s;
printf( "%d\n", s.s.i );
return 0;
}

----------

With version 1 of the S2 constructor the program will spew random
values as expected.
With version 2 of the S2 constructor the program only spews zeros.
Does explicitly calling the default constructor in the member
initialization list somehow cause the "default" constructor for the
int in S1 to be called?
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-01-2008
* http://www.velocityreviews.com/forums/(E-Mail Removed):
> struct S1
> {
> int i;
> };
>
> struct S2 {
> S1 s;
> // version 1
> S2() {} ;
> // version 2
> S2() : s() {} ;
> };
>
> int main()
> {
> S2 s;
> printf( "%d\n", s.s.i );
> return 0;
> }
>
> ----------
>
> With version 1 of the S2 constructor the program will spew random
> values as expected.
> With version 2 of the S2 constructor the program only spews zeros.
> Does explicitly calling the default constructor in the member
> initialization list somehow cause the "default" constructor for the
> int in S1 to be called?


No, an int does not have a constructor: the initialization syntax just
resembles an explicit constructor call.

Since you initialize the member it is initialized.

In standard C++ this initialization syntax also works for an array
member, although compiler support for that varies.

Cheers, & hth

- Alf


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
 
 
 
devp
Guest
Posts: n/a
 
      02-01-2008
On Feb 1, 5:18 am, (E-Mail Removed) wrote:
> struct S1
> {
> int i;
>
> };
>
> struct S2 {
> S1 s;
> // version 1
> S2() {} ;
> // version 2
> S2() : s() {} ;
>
> };
>
> int main()
> {
> S2 s;
> printf( "%d\n", s.s.i );
> return 0;
>
> }
>
> ----------
>
> With version 1 of the S2 constructor the program will spew random
> values as expected.
> With version 2 of the S2 constructor the program only spews zeros.
> Does explicitly calling the default constructor in the member
> initialization list somehow cause the "default" constructor for the
> int in S1 to be called?


Hi
I tried the program with g++ it works same both ways, as should. Which
compiler did you use?

cheers
projyal
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-01-2008
* devp:
> On Feb 1, 5:18 am, (E-Mail Removed) wrote:
>> struct S1
>> {
>> int i;
>>
>> };
>>
>> struct S2 {
>> S1 s;
>> // version 1
>> S2() {} ;
>> // version 2
>> S2() : s() {} ;
>>
>> };
>>
>> int main()
>> {
>> S2 s;
>> printf( "%d\n", s.s.i );
>> return 0;
>>
>> }
>>
>> ----------
>>
>> With version 1 of the S2 constructor the program will spew random
>> values as expected.
>> With version 2 of the S2 constructor the program only spews zeros.
>> Does explicitly calling the default constructor in the member
>> initialization list somehow cause the "default" constructor for the
>> int in S1 to be called?

>
> Hi
> I tried the program with g++ it works same both ways, as should.


Version 1 has undefined behavior.

Undefined behavior includes doing what one incorrectly might expect.


> Which compiler did you use?


Different compilers, versions of the same compiler, and invocations of
the same version of the same compiler but with different options, often
yield different results for undefined behavior.

Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
mhvaughn@gmail.com
Guest
Posts: n/a
 
      02-01-2008
On Jan 31, 5:17 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * (E-Mail Removed):
>
>
>
> > struct S1
> > {
> > int i;
> > };

>
> > struct S2 {
> > S1 s;
> > // version 1
> > S2() {} ;
> > // version 2
> > S2() : s() {} ;
> > };

>
> > int main()
> > {
> > S2 s;
> > printf( "%d\n", s.s.i );
> > return 0;
> > }

>
> > ----------

>
> > With version 1 of the S2 constructor the program will spew random
> > values as expected.
> > With version 2 of the S2 constructor the program only spews zeros.
> > Does explicitly calling the default constructor in the member
> > initialization list somehow cause the "default" constructor for the
> > int in S1 to be called?

>
> No, an int does not have a constructor: the initialization syntax just
> resembles an explicit constructor call.
>
> Since you initialize the member it is initialized.
>


But the member I initialized is of type S1. Since there is no
constructor provided for S1 the compiler should provide one which
should do nothing. I'm perfectly willing to accept that it just seems
like its doing something, I guess I just wanted to double-check that
default constructors in member initialization lists are not special in
some way (e.g., like global structs whose members are zeroed out when
created).

> In standard C++ this initialization syntax also works for an array
> member, although compiler support for that varies.
>
> Cheers, & hth
>
> - Alf
>
> --
> A: Because it messes up the order in which people normally read text.
> Q: Why is it such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing on usenet and in e-mail?


 
Reply With Quote
 
mhvaughn@gmail.com
Guest
Posts: n/a
 
      02-01-2008
On Jan 31, 5:22 pm, devp <(E-Mail Removed)> wrote:
> On Feb 1, 5:18 am, (E-Mail Removed) wrote:
>
>
>
> > struct S1
> > {
> > int i;

>
> > };

>
> > struct S2 {
> > S1 s;
> > // version 1
> > S2() {} ;
> > // version 2
> > S2() : s() {} ;

>
> > };

>
> > int main()
> > {
> > S2 s;
> > printf( "%d\n", s.s.i );
> > return 0;

>
> > }

>
> > ----------

>
> > With version 1 of the S2 constructor the program will spew random
> > values as expected.
> > With version 2 of the S2 constructor the program only spews zeros.
> > Does explicitly calling the default constructor in the member
> > initialization list somehow cause the "default" constructor for the
> > int in S1 to be called?

>
> Hi
> I tried the program with g++ it works same both ways, as should. Which
> compiler did you use?


[615]$g++ -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c+
+,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-
system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-
threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/
4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu
--enable-libstdcxx-debug --enable-mpfr --enable-checking=release
x86_64-linux-gnu
Thread model: posix
gcc version 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)


>
> cheers
> projyal


 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-01-2008
* (E-Mail Removed):
> On Jan 31, 5:17 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
>> * (E-Mail Removed):
>>
>>> struct S1
>>> {
>>> int i;
>>> };
>>> struct S2 {
>>> S1 s;
>>> // version 1
>>> S2() {} ;
>>> // version 2
>>> S2() : s() {} ;
>>> };
>>> int main()
>>> {
>>> S2 s;
>>> printf( "%d\n", s.s.i );
>>> return 0;
>>> }
>>> ----------
>>> With version 1 of the S2 constructor the program will spew random
>>> values as expected.
>>> With version 2 of the S2 constructor the program only spews zeros.
>>> Does explicitly calling the default constructor in the member
>>> initialization list somehow cause the "default" constructor for the
>>> int in S1 to be called?

>> No, an int does not have a constructor: the initialization syntax just
>> resembles an explicit constructor call.
>>
>> Since you initialize the member it is initialized.
>>

>
> But the member I initialized is of type S1.


Previous comment still applies, but to be honest, I didn't notice...


> Since there is no
> constructor provided for S1 the compiler should provide one which
> should do nothing.


If it's used (ref. 12.1/7).

But, the language being as backwards in certain respects as it is, to
use that do-nothing automatic default constructor you have to /not/
indicate that you want it, e.g. for a local variable,

S1 o; // Do-nothing auto default constructor used, 12.1/8.

If you try to add parentheses to say you want to use the darned thing,
then in the C++ "do the opposite of what's expected"-way it isn't used:

o = S1(); // Not an invocation of the do-nothing def. constructor.

What happens here is according to C++98 a zero-initialization (8.5/7,
8.5/5) and IIRC according to C++03 a value-initialization, essentially
zeroing or default-initializing members depending on whether they have
user-defined default constructors or not. And the same applies to your
code above, in the second version. So the int is zeroed, and that
zeroing does not involve a constructor, not even of S1.


> I'm perfectly willing to accept that it just seems
> like its doing something, I guess I just wanted to double-check that
> default constructors in member initialization lists are not special in
> some way (e.g., like global structs whose members are zeroed out when
> created).


You're not using the S1 default constructor; see above.


Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      02-01-2008
(E-Mail Removed) wrote:
> struct S1
> {
> int i;
> };
>
> struct S2 {
> S1 s;
> // version 1
> S2() {} ;
> // version 2
> S2() : s() {} ;
> };
>
> int main()
> {
> S2 s;
> printf( "%d\n", s.s.i );
> return 0;
> }
>
> ----------
>
> With version 1 of the S2 constructor the program will spew random
> values as expected.


OK.

> With version 2 of the S2 constructor the program only spews zeros.


Yes.

> Does explicitly calling the default constructor in the member
> initialization list somehow cause the "default" constructor for the
> int in S1 to be called?


Firstly, you are not "explicitly calling" the default constructor of S1
by using 's()' syntax in the constructor initializer list. In C++
there's no syntax and way in general to "explicitly call" a constructor.

Secondly, only obects of class types can have constructors in C++.
Objects of type 'int' (as 'S1::i' in your case) have no construtors
whatsoever.

Now, when you specify a '()' initializer for an object, it causes so
called "value-initialization" of that object. Note, that the notion of
"initialization" in C++ is more general that the notion of
"construction". Initialization does not necessarily involve construction
(and constructors). For an object of class type without any user-defined
constructors (like 's' of type 'S1' in your example),
value-initialization does not involve any constructors of S1.
Value-initialization for an object of type S1 results in
value-initialization of all of its subobjects. In this case it is
value-initialization if 'S1::i' member of type 'int'. For type 'int'
value-initialization means zero-initialization. I.e. 'S1::i' is set to
zero. It is done directly, without involving any constructors.

Note once again, that the only constructor that is involved in this
process is the constructor of 'S2'. There are no more constructors
involved here. 'S1' and its member 'S1::i' are initialized directly.

--
Best regards,
Andrey Tarasevich
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-01-2008
* Andrey Tarasevich:
> (E-Mail Removed) wrote:
>> struct S1
>> {
>> int i;
>> };
>>
>> struct S2 {
>> S1 s;
>> // version 1
>> S2() {} ;
>> // version 2
>> S2() : s() {} ;
>> };
>>
>> int main()
>> {
>> S2 s;
>> printf( "%d\n", s.s.i );
>> return 0;
>> }
>>
>> ----------
>>
>> With version 1 of the S2 constructor the program will spew random
>> values as expected.

>
> OK.
>
>> With version 2 of the S2 constructor the program only spews zeros.

>
> Yes.
>
>> Does explicitly calling the default constructor in the member
>> initialization list somehow cause the "default" constructor for the
>> int in S1 to be called?

>
> Firstly, you are not "explicitly calling" the default constructor of S1
> by using 's()' syntax in the constructor initializer list.


Right.


> In C++
> there's no syntax and way in general to "explicitly call" a constructor.


I'm sorry, that's incorrect.

There's no dedicated C++ syntax for constructor calls. What the syntax
means depends on context. Whether to say that an explicit constructor
call is an explicit constructor call is a terminologial issue.

The language's creator calls an explicit constructor call an explicit
constructor call. Some programmers who post in this newsgroup have
taken issue with that, insisting that the word "call" is inappropriate
for source code level constructor calls, thus rendering e.g. the
standard's definition of default constructor (what we're discussing
here) meaningless. But to each his own, just don't propagate the myth
that that terminological stance has any substance.


Cheers, & hth.,

- Alf


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Andrey Tarasevich
Guest
Posts: n/a
 
      02-01-2008
Alf P. Steinbach wrote:
> ...
>> In C++ there's no syntax and way in general to "explicitly call" a
>> constructor.

>
> I'm sorry, that's incorrect.
>
> There's no dedicated C++ syntax for constructor calls. What the syntax
> means depends on context. Whether to say that an explicit constructor
> call is an explicit constructor call is a terminologial issue.


I disagree. Constructors are functions. They are special functions, but
functions nevertheless. For this reason I'd expect the "explicit
constructor call", if it existed, to be have the function call
semantics. However, if I'm not mistaken, there's no way to call
constructor in C++ by using function call semantics. Constructors calls
in C++ are "side effects" of the more generic process called
"initialization". It is is invoked by various language constructs
having... well, initialization semantics, which is essentially different
from function call semantics. This is why I say that there's no way to
"call" a constructor in C++.

> The language's creator calls an explicit constructor call an explicit
> constructor call.


Where? In TC++PL? If yes, then sorry, but that book is not canonical in
the context of ANSI standard C++ discussion. It is intentionally
simplified to be more accessible for newcomers. And the price of that
simplification is that sometimes it makes statements, which are simply
incorrect from the standard C++ point of view. (For example, it states
that scalar types have constructors, if I remember correctly).

--
Best regards,
Andrey Tarasevich
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
help on constructor/constructor initialization list with inheritanceusing templates balaji C++ 3 08-10-2011 12:06 PM
initialization of array as a member using the initialization list aaragon C++ 2 11-02-2008 04:57 PM
A constructor calling another constructor (default constructor)? Generic Usenet Account C++ 10 11-28-2007 04:12 AM
How to initialize an array member in the member initialization list? jut_bit_zx@eyou.com C++ 3 10-10-2005 12:10 AM
Tkinter WEIRDNESS or Python WEIRDNESS? steve Python 4 03-13-2005 12:34 AM



Advertisments