Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > static member object initialization

Reply
Thread Tools

static member object initialization

 
 
subramanian100in@yahoo.com, India
Guest
Posts: n/a
 
      09-25-2007
Consider the following program:

#include <iostream>

using namespace std;

class Test
{
static Test t;
static Test init_Test( ) { return t; }
Test(const Test & rhs) { cout << "copy ctor" << endl; }
};

Test Test::t = init_Test( );

int main()
{
return 0;
}

This program compiles fine under both g++ and VC++2005 Express Edition
and both produce the following same output
copy ctor

However consider the statement
Test Test::t = init_Test( );
Here init_Test( ) is called which returns the static member object
under construction which is 't'. I do not understand how we can
return an object which is still under construction.
How is it accepted by the compiler ?

Kindly explain

Thanks
V.Subramanian

 
Reply With Quote
 
 
 
 
Jonathan Lane
Guest
Posts: n/a
 
      09-25-2007
Try putting in a default constructor that writes some output. I think
that will show you what's going on. Also, you're not returning t
you're returning a copy of t.

On Sep 25, 12:47 pm, "(E-Mail Removed), India"
<(E-Mail Removed)> wrote:
> Consider the following program:
>
> #include <iostream>
>
> using namespace std;
>
> class Test
> {
> static Test t;
> static Test init_Test( ) { return t; }
> Test(const Test & rhs) { cout << "copy ctor" << endl; }
>
> };
>
> Test Test::t = init_Test( );
>
> int main()
> {
> return 0;
>
> }
>
> This program compiles fine under both g++ and VC++2005 Express Edition
> and both produce the following same output
> copy ctor
>
> However consider the statement
> Test Test::t = init_Test( );
> Here init_Test( ) is called which returns the static member object
> under construction which is 't'. I do not understand how we can
> return an object which is still under construction.
> How is it accepted by the compiler ?
>
> Kindly explain
>
> Thanks
> V.Subramanian



 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      09-25-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Consider the following program:
>
> #include <iostream>
>
> using namespace std;
>
> class Test
> {
> static Test t;
> static Test init_Test( ) { return t; }
> Test(const Test & rhs) { cout << "copy ctor" << endl; }
> };
>
> Test Test::t = init_Test( );
>
> int main()
> {
> return 0;
> }
>
> This program compiles fine under both g++ and VC++2005 Express Edition
> and both produce the following same output
> copy ctor
>
> However consider the statement
> Test Test::t = init_Test( );
> Here init_Test( ) is called which returns the static member object
> under construction which is 't'. I do not understand how we can
> return an object which is still under construction.
> How is it accepted by the compiler ?


How should the compiler be able to catch your *logical* errors? The
compiler is not obligated to tell you your logic is incorrect. Or
that you have a chicken and egg problem. The compiler just checks
the syntax and types. Your code has undefined behaviour since it
makes an attempt to use an uninitialised object. The same thing as
here:

int &r = r;

I think the compiler is not required to find and flag all instances of
undefined behaviour in your code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Barry
Guest
Posts: n/a
 
      09-25-2007
(E-Mail Removed), India wrote:
> Consider the following program:
>
> #include <iostream>
>
> using namespace std;
>
> class Test
> {
> static Test t;
> static Test init_Test( ) { return t; }
> Test(const Test & rhs) { cout << "copy ctor" << endl; }
> };
>
> Test Test::t = init_Test( );
>
> int main()
> {
> return 0;
> }
>
> This program compiles fine under both g++ and VC++2005 Express Edition
> and both produce the following same output
> copy ctor
>
> However consider the statement
> Test Test::t = init_Test( );
> Here init_Test( ) is called which returns the static member object
> under construction which is 't'. I do not understand how we can
> return an object which is still under construction.
> How is it accepted by the compiler ?
>


This is stunning, and even puzzling that "init_Test()' compiles, which
should be Test::init_Test(); to be well-formed, I think

Comeau online also accepts all the cases.
Waiting guru for explanation.


--
Thanks
Barry
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      09-25-2007
Barry wrote:
> (E-Mail Removed), India wrote:
>> Consider the following program:
>>
>> #include <iostream>
>>
>> using namespace std;
>>
>> class Test
>> {
>> static Test t;
>> static Test init_Test( ) { return t; }
>> Test(const Test & rhs) { cout << "copy ctor" << endl; }
>> };
>>
>> Test Test::t = init_Test( );
>>
>> int main()
>> {
>> return 0;
>> }
>>
>> This program compiles fine under both g++ and VC++2005 Express
>> Edition and both produce the following same output
>> copy ctor
>>
>> However consider the statement
>> Test Test::t = init_Test( );
>> Here init_Test( ) is called which returns the static member object
>> under construction which is 't'. I do not understand how we can
>> return an object which is still under construction.
>> How is it accepted by the compiler ?
>>

>
> This is stunning, and even puzzling that "init_Test()' compiles, which
> should be Test::init_Test(); to be well-formed, I think
>
> Comeau online also accepts all the cases.
> Waiting guru for explanation.


Since you're defining 't' that is declared inside 'Test', 'Test' scope
is also looked up. I am sure you can find it somewhere in subclause
3.4 (name lookup).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Barry
Guest
Posts: n/a
 
      09-25-2007
Victor Bazarov wrote:
> (E-Mail Removed) wrote:
>> Consider the following program:
>>
>> #include <iostream>
>>
>> using namespace std;
>>
>> class Test
>> {
>> static Test t;
>> static Test init_Test( ) { return t; }
>> Test(const Test & rhs) { cout << "copy ctor" << endl; }
>> };
>>
>> Test Test::t = init_Test( );
>>
>> int main()
>> {
>> return 0;
>> }
>>
>> This program compiles fine under both g++ and VC++2005 Express Edition
>> and both produce the following same output
>> copy ctor
>>
>> However consider the statement
>> Test Test::t = init_Test( );
>> Here init_Test( ) is called which returns the static member object
>> under construction which is 't'. I do not understand how we can
>> return an object which is still under construction.
>> How is it accepted by the compiler ?

>
> How should the compiler be able to catch your *logical* errors? The
> compiler is not obligated to tell you your logic is incorrect. Or
> that you have a chicken and egg problem. The compiler just checks
> the syntax and types. Your code has undefined behaviour since it
> makes an attempt to use an uninitialised object. The same thing as
> here:
>
> int &r = r;
>
> I think the compiler is not required to find and flag all instances of
> undefined behaviour in your code.
>



Well, the code from the OP, do have the "chicken and egg" problem, while
this one does not:

class A
{
static A a;
static A Init() { return A(); }
A() {}
};

A A::a = A::Init();
// or even
//A A::a = Init();

int main()
{
}

the code above compiles with Comeau online


--
Thanks
Barry
 
Reply With Quote
 
Jonathan Lane
Guest
Posts: n/a
 
      09-25-2007
On Sep 25, 2:02 pm, Barry <(E-Mail Removed)> wrote:
> Victor Bazarov wrote:
> > (E-Mail Removed) wrote:
> >> Consider the following program:

>
> >> #include <iostream>

>
> >> using namespace std;

>
> >> class Test
> >> {
> >> static Test t;
> >> static Test init_Test( ) { return t; }
> >> Test(const Test & rhs) { cout << "copy ctor" << endl; }
> >> };

>
> >> Test Test::t = init_Test( );

>
> >> int main()
> >> {
> >> return 0;
> >> }

>
> >> This program compiles fine under both g++ and VC++2005 Express Edition
> >> and both produce the following same output
> >> copy ctor

>
> >> However consider the statement
> >> Test Test::t = init_Test( );


I would think that:
Test Test::t <- this part runs the default ctor
= init_Test() <- this part then calls operator=() on the newly
constructed Test object. init_Test then returns t by value so you end
up with a statement like:
Test Test::t = Test(Test::t);
Or am I missing the point here?

 
Reply With Quote
 
Barry
Guest
Posts: n/a
 
      09-25-2007
Jonathan Lane wrote:
> On Sep 25, 2:02 pm, Barry <(E-Mail Removed)> wrote:
>> Victor Bazarov wrote:
>>> (E-Mail Removed) wrote:
>>>> Consider the following program:
>>>> #include <iostream>
>>>> using namespace std;
>>>> class Test
>>>> {
>>>> static Test t;
>>>> static Test init_Test( ) { return t; }
>>>> Test(const Test & rhs) { cout << "copy ctor" << endl; }
>>>> };
>>>> Test Test::t = init_Test( );
>>>> int main()
>>>> {
>>>> return 0;
>>>> }
>>>> This program compiles fine under both g++ and VC++2005 Express Edition
>>>> and both produce the following same output
>>>> copy ctor
>>>> However consider the statement
>>>> Test Test::t = init_Test( );

>
> I would think that:
> Test Test::t <- this part runs the default ctor
> = init_Test() <- this part then calls operator=() on the newly
> constructed Test object. init_Test then returns t by value so you end
> up with a statement like:
> Test Test::t = Test(Test::t);
> Or am I missing the point here?
>


My point is that whichever "Init()" or "A::Init()" is private member
function, why access control does not apply here.

--
Thanks
Barry
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      09-25-2007
Jonathan Lane wrote:
> On Sep 25, 2:02 pm, Barry <(E-Mail Removed)> wrote:
>> Victor Bazarov wrote:
>>> (E-Mail Removed) wrote:
>>>> Consider the following program:

>>
>>>> #include <iostream>

>>
>>>> using namespace std;

>>
>>>> class Test
>>>> {
>>>> static Test t;
>>>> static Test init_Test( ) { return t; }
>>>> Test(const Test & rhs) { cout << "copy ctor" << endl; }
>>>> };

>>
>>>> Test Test::t = init_Test( );

>>
>>>> int main()
>>>> {
>>>> return 0;
>>>> }

>>
>>>> This program compiles fine under both g++ and VC++2005 Express
>>>> Edition and both produce the following same output
>>>> copy ctor

>>
>>>> However consider the statement
>>>> Test Test::t = init_Test( );

>
> I would think that:
> Test Test::t <- this part runs the default ctor
> = init_Test() <- this part then calls operator=() on the newly
> constructed Test object. init_Test then returns t by value so you end
> up with a statement like:
> Test Test::t = Test(Test::t);
> Or am I missing the point here?


Not only you're missing the point. You're also missing the fact that
'init_Test' is a function and not an object. And you're also missing
the fact that the statement

Blah Blah::blah = blahblah();

has no default constructor involved at all. It's called "copy-
initialisation" and relates to copy construction. 'blahblah' would
return a temporary (whatever way is used to construct it), and then
the 'blah' object is copy-constructed from that temporary.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Barry
Guest
Posts: n/a
 
      09-25-2007
Jonathan Lane wrote:
> On Sep 25, 2:02 pm, Barry <(E-Mail Removed)> wrote:
>> Victor Bazarov wrote:
>>> (E-Mail Removed) wrote:
>>>> Consider the following program:
>>>> #include <iostream>
>>>> using namespace std;
>>>> class Test
>>>> {
>>>> static Test t;
>>>> static Test init_Test( ) { return t; }
>>>> Test(const Test & rhs) { cout << "copy ctor" << endl; }
>>>> };
>>>> Test Test::t = init_Test( );
>>>> int main()
>>>> {
>>>> return 0;
>>>> }
>>>> This program compiles fine under both g++ and VC++2005 Express Edition
>>>> and both produce the following same output
>>>> copy ctor
>>>> However consider the statement
>>>> Test Test::t = init_Test( );

>
> I would think that:
> Test Test::t <- this part runs the default ctor
> = init_Test() <- this part then calls operator=() on the newly
> constructed Test object. init_Test then returns t by value so you end
> up with a statement like:
> Test Test::t = Test(Test::t);
> Or am I missing the point here?
>

class A
{
static A a;
static int i;

static A Init() { return A(); }
static int GetInt() {return 10;}

A() {}
};

A A::a = A::Init();
int A::i = A::GetInt();

int main()
{
}

well, I think I got a point,

the initialization of static member data(no matter private/public), the
initialization statement creates a scope, in this special scope, all
member functions can be called.
I don't know whether Victor meant this else thread.

But if we initiate a global object of A like this:

A a1 = A::Init();

No way, A::Init() is private.

--
Thanks
Barry
 
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
initialization of array as a member using the initialization list aaragon C++ 2 11-02-2008 04:57 PM
error C2614: 'CYYYRegister' : illegal member initialization:'CRequest' is not a base or member Angus C++ 1 03-06-2008 11:38 AM
Can a static member function access non-static member? dolphin C++ 3 12-05-2007 12:39 PM
copy-initialization and class object as static member subramanian100in@yahoo.com, India C++ 2 11-13-2007 05:21 PM
How to initialize an array member in the member initialization list? jut_bit_zx@eyou.com C++ 3 10-10-2005 12:10 AM



Advertisments