[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Query with constructor calls

Vijay Meena

10/19/2008 3:33:00 AM

Hi,
This code is of no use. But I am just curious to know about what
happening here.

#include <iostream>
using namespace std;

class Foo {
private:
int i;
public:
Foo() {
cout << "Foo::Foo()" << endl;
Foo(i);
}
Foo(int i) : i(i) {
cout << "Foo::Foo(int)" << endl;
}
~Foo() {
cout << "Foo::~Foo()" << endl;
}
};

int main(int argc, char *argv[])
{
Foo();
}

I am getting infinite call to "Foo::Foo()". Program is not even
executing "Foo::Foo(int)".

Vijay

11 Answers

Kai-Uwe Bux

10/19/2008 3:55:00 AM

0

Vijay Meena wrote:

> Hi,
> This code is of no use. But I am just curious to know about what
> happening here.
>
> #include <iostream>
> using namespace std;
>
> class Foo {
> private:
> int i;
> public:
> Foo() {
> cout << "Foo::Foo()" << endl;
> Foo(i);
> }
> Foo(int i) : i(i) {
> cout << "Foo::Foo(int)" << endl;
> }
> ~Foo() {
> cout << "Foo::~Foo()" << endl;
> }
> };
>
> int main(int argc, char *argv[])
> {
> Foo();
> }
>
> I am getting infinite call to "Foo::Foo()". Program is not even
> executing "Foo::Foo(int)".

Hm, I am flabbergasted. The following _does_ the expected:

Foo() {
cout << "Foo::Foo()" << endl;
Foo( this->i );
}

and prints:

Foo::Foo()
Foo::Foo(int)
Foo::~Foo()
Foo::~Foo()

I have no idea, what difference the "this->" should make.

BTW: initializing i in the constructor does not help (although the program
might have UB without doing so).



Best

Kai-Uwe Bux

Sam

10/19/2008 4:39:00 AM

0

Kai-Uwe Bux writes:

> Vijay Meena wrote:
>
>> Hi,
>> This code is of no use. But I am just curious to know about what
>> happening here.
>>
>> #include <iostream>
>> using namespace std;
>>
>> class Foo {
>> private:
>> int i;
>> public:
>> Foo() {
>> cout << "Foo::Foo()" << endl;
>> Foo(i);
>> }
>> Foo(int i) : i(i) {
>> cout << "Foo::Foo(int)" << endl;
>> }
>> ~Foo() {
>> cout << "Foo::~Foo()" << endl;
>> }
>> };
>>
>> int main(int argc, char *argv[])
>> {
>> Foo();
>> }
>>
>> I am getting infinite call to "Foo::Foo()". Program is not even
>> executing "Foo::Foo(int)".
>
> Hm, I am flabbergasted. The following _does_ the expected:
>
> Foo() {
> cout << "Foo::Foo()" << endl;
> Foo( this->i );
> }
>
> and prints:
>
> Foo::Foo()
> Foo::Foo(int)
> Foo::~Foo()
> Foo::~Foo()
>
> I have no idea, what difference the "this->" should make.
>
> BTW: initializing i in the constructor does not help (although the program
> might have UB without doing so).

This looks like a bug in gcc (4.3.0, in my case).

Dissassembly shows that Foo(i) gets compiled into Foo().


ebony.soft

10/19/2008 6:20:00 AM

0

On Oct 19, 6:32 am, Vijay Meena <vijay.me...@gmail.com> wrote:
> Hi,
> This code is of no use. But I am just curious to know about what
> happening here.
>
> #include <iostream>
> using namespace std;
>
> class Foo {
> private:
>         int i;
> public:
>         Foo() {
>                 cout << "Foo::Foo()" << endl;
>                 Foo(i);
>         }
>         Foo(int i) : i(i) {
>                 cout << "Foo::Foo(int)" << endl;
>         }
>         ~Foo() {
>                 cout << "Foo::~Foo()" << endl;
>         }
>
> };
>
> int main(int argc, char *argv[])
> {
>         Foo();
>
> }
>
> I am getting infinite call to "Foo::Foo()". Program is not even
> executing "Foo::Foo(int)".
>
> Vijay


Hi

I ran your code in VS 2005 and I got the following output
indefinitely:
Foo()
Foo()
....

of course, compiler issued the following warning:
warning C4717: 'Foo::Foo' : recursive on all control paths, function
will cause runtime stack overflow
as Kai wrote, if we change
Foo(i);
to
Foo(this->i);
we get the expected output:
Foo::Foo()
Foo::Foo(int)
Foo::~Foo()
Foo::~Foo()

There is a side point: There are some recommendations that don't call
a constructor inside the body of another constructor:
http://www.parashift.com/c++-faq-lite/ctors.htm...

Regards,
Saeed Amrollahi


CockneyWinker

10/19/2008 6:49:00 AM

0


"Vijay Meena" <vijay.meena@gmail.com> wrote in message
news:a72193b7-f0d2-4209-a86e-d0d1529ac1be@79g2000hsk.googlegroups.com...
> Hi,
> This code is of no use. But I am just curious to know about what
> happening here.
>
> #include <iostream>
> using namespace std;
>
> class Foo {
> private:
> int i;
> public:
> Foo() {
> cout << "Foo::Foo()" << endl;
> Foo(i);
> }
> Foo(int i) : i(i) {
> cout << "Foo::Foo(int)" << endl;
> }
> ~Foo() {
> cout << "Foo::~Foo()" << endl;
> }
> };
>
> int main(int argc, char *argv[])
> {
> Foo();
> }
>
> I am getting infinite call to "Foo::Foo()". Program is not even
> executing "Foo::Foo(int)".
>
> Vijay
>
The problem is that the line Foo(i) is equivalent to Foo i, so you are
constructing
another Foo object with the default constructor each time you construct a
foo, hence the recursion.
The following code illustrates the equivalence of Bar y and Bar(x).
class Bar

{

public:

Bar()

{}

void dobar(){}

};

int main(int argc, char *argv[])

{

Bar y;

Bar (x);

x.dobar();

y.dobar();

return 0;

}




CockneyWinker

10/19/2008 6:53:00 AM

0


"Vijay Meena" <vijay.meena@gmail.com> wrote in message
news:a72193b7-f0d2-4209-a86e-d0d1529ac1be@79g2000hsk.googlegroups.com...
> Hi,
> This code is of no use. But I am just curious to know about what
> happening here.
>
> #include <iostream>
> using namespace std;
>
> class Foo {
> private:
> int i;
> public:
> Foo() {
> cout << "Foo::Foo()" << endl;
> Foo(i);
> }
> Foo(int i) : i(i) {
> cout << "Foo::Foo(int)" << endl;
> }
> ~Foo() {
> cout << "Foo::~Foo()" << endl;
> }
> };
>
> int main(int argc, char *argv[])
> {
> Foo();
> }
>
> I am getting infinite call to "Foo::Foo()". Program is not even
> executing "Foo::Foo(int)".
>
> Vijay
>

Just another follow up to my earlier post. When I compile this on VS
2005/2008, I get a compiler warning about
recursive constructor.


Erik Wikström

10/19/2008 8:44:00 AM

0

On 2008-10-19 06:39, Sam wrote:
> Kai-Uwe Bux writes:
>
>> Vijay Meena wrote:
>>
>>> Hi,
>>> This code is of no use. But I am just curious to know about what
>>> happening here.
>>>
>>> #include <iostream>
>>> using namespace std;
>>>
>>> class Foo {
>>> private:
>>> int i;
>>> public:
>>> Foo() {
>>> cout << "Foo::Foo()" << endl;
>>> Foo(i);
>>> }
>>> Foo(int i) : i(i) {
>>> cout << "Foo::Foo(int)" << endl;
>>> }
>>> ~Foo() {
>>> cout << "Foo::~Foo()" << endl;
>>> }
>>> };
>>>
>>> int main(int argc, char *argv[])
>>> {
>>> Foo();
>>> }
>>>
>>> I am getting infinite call to "Foo::Foo()". Program is not even
>>> executing "Foo::Foo(int)".
>>
>> Hm, I am flabbergasted. The following _does_ the expected:
>>
>> Foo() {
>> cout << "Foo::Foo()" << endl;
>> Foo( this->i );
>> }
>>
>> and prints:
>>
>> Foo::Foo()
>> Foo::Foo(int)
>> Foo::~Foo()
>> Foo::~Foo()
>>
>> I have no idea, what difference the "this->" should make.
>>
>> BTW: initializing i in the constructor does not help (although the program
>> might have UB without doing so).
>
> This looks like a bug in gcc (4.3.0, in my case).

MSVC behaves the same way.

--
Erik Wikström

Kai-Uwe Bux

10/19/2008 9:05:00 AM

0

Erik Wikström wrote:

> On 2008-10-19 06:39, Sam wrote:
>> Kai-Uwe Bux writes:
>>
>>> Vijay Meena wrote:
>>>
>>>> Hi,
>>>> This code is of no use. But I am just curious to know about what
>>>> happening here.
>>>>
>>>> #include <iostream>
>>>> using namespace std;
>>>>
>>>> class Foo {
>>>> private:
>>>> int i;
>>>> public:
>>>> Foo() {
>>>> cout << "Foo::Foo()" << endl;
>>>> Foo(i);
>>>> }
>>>> Foo(int i) : i(i) {
>>>> cout << "Foo::Foo(int)" << endl;
>>>> }
>>>> ~Foo() {
>>>> cout << "Foo::~Foo()" << endl;
>>>> }
>>>> };
>>>>
>>>> int main(int argc, char *argv[])
>>>> {
>>>> Foo();
>>>> }
>>>>
>>>> I am getting infinite call to "Foo::Foo()". Program is not even
>>>> executing "Foo::Foo(int)".
>>>
>>> Hm, I am flabbergasted. The following _does_ the expected:
>>>
>>> Foo() {
>>> cout << "Foo::Foo()" << endl;
>>> Foo( this->i );
>>> }
>>>
>>> and prints:
>>>
>>> Foo::Foo()
>>> Foo::Foo(int)
>>> Foo::~Foo()
>>> Foo::~Foo()
>>>
>>> I have no idea, what difference the "this->" should make.
>>>
>>> BTW: initializing i in the constructor does not help (although the
>>> program might have UB without doing so).
>>
>> This looks like a bug in gcc (4.3.0, in my case).
>
> MSVC behaves the same way.

I think that CockneyWinker has the solution in his posting:

The problem is that the line Foo(i) is equivalent to Foo i, ...

This seems to go against [5.2.3/1], but only if the line could not be parsed
as a declaration. By [6.8/1] it seems that is can.


Best

Kai-Uwe Bux

Vijay Meena

10/19/2008 10:18:00 AM

0

On Oct 19, 2:05 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Erik Wikström wrote:
> > On 2008-10-19 06:39, Sam wrote:
> >> Kai-Uwe Bux writes:
>
> >>> Vijay Meena wrote:
>
> >>>> Hi,
> >>>> This code is of no use. But I am just curious to know about what
> >>>> happening here.
>
> >>>> #include <iostream>
> >>>> using namespace std;
>
> >>>> class Foo {
> >>>> private:
> >>>> int i;
> >>>> public:
> >>>> Foo() {
> >>>> cout << "Foo::Foo()" << endl;
> >>>> Foo(i);
> >>>> }
> >>>> Foo(int i) : i(i) {
> >>>> cout << "Foo::Foo(int)" << endl;
> >>>> }
> >>>> ~Foo() {
> >>>> cout << "Foo::~Foo()" << endl;
> >>>> }
> >>>> };
>
> >>>> int main(int argc, char *argv[])
> >>>> {
> >>>> Foo();
> >>>> }
>
> >>>> I am getting infinite call to "Foo::Foo()". Program is not even
> >>>> executing "Foo::Foo(int)".
>
> >>> Hm, I am flabbergasted. The following _does_ the expected:
>
> >>>         Foo() {
> >>>           cout << "Foo::Foo()" << endl;
> >>>           Foo( this->i );
> >>>         }
>
> >>> and prints:
>
> >>>   Foo::Foo()
> >>>   Foo::Foo(int)
> >>>   Foo::~Foo()
> >>>   Foo::~Foo()
>
> >>> I have no idea, what difference the "this->" should make.
>
> >>> BTW: initializing i in the constructor does not help (although the
> >>> program might have UB without doing so).
>
> >> This looks like a bug in gcc (4.3.0, in my case).
>
> > MSVC behaves the same way.
>
> I think that CockneyWinker has the solution in his posting:
>
>   The problem is that the line Foo(i) is equivalent to Foo i, ...
>
> This seems to go against [5.2.3/1], but only if the line could not be parsed
> as a declaration. By [6.8/1] it seems that is can.
>
> Best
>
> Kai-Uwe Bux

Yes, It seems so. When I change Foo(i) to Foo((int)i) or Foo(2) then
it behaves properly. But why does it need _extra_ typecast ? can't it
see that _i_ is declared as an int ? I am sorry, I don't have much
experience with C++. I still couldn't understand that how Foo(i) is
equal to *Foo i* ?

Erik Wikström

10/19/2008 10:29:00 AM

0

On 2008-10-19 12:18, Vijay Meena wrote:
> On Oct 19, 2:05 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>> Erik Wikström wrote:
>> > On 2008-10-19 06:39, Sam wrote:
>> >> Kai-Uwe Bux writes:
>>
>> >>> Vijay Meena wrote:
>>
>> >>>> Hi,
>> >>>> This code is of no use. But I am just curious to know about what
>> >>>> happening here.
>>
>> >>>> #include <iostream>
>> >>>> using namespace std;
>>
>> >>>> class Foo {
>> >>>> private:
>> >>>> int i;
>> >>>> public:
>> >>>> Foo() {
>> >>>> cout << "Foo::Foo()" << endl;
>> >>>> Foo(i);
>> >>>> }
>> >>>> Foo(int i) : i(i) {
>> >>>> cout << "Foo::Foo(int)" << endl;
>> >>>> }
>> >>>> ~Foo() {
>> >>>> cout << "Foo::~Foo()" << endl;
>> >>>> }
>> >>>> };
>>
>> >>>> int main(int argc, char *argv[])
>> >>>> {
>> >>>> Foo();
>> >>>> }
>>
>> >>>> I am getting infinite call to "Foo::Foo()". Program is not even
>> >>>> executing "Foo::Foo(int)".
>>
>> >>> Hm, I am flabbergasted. The following _does_ the expected:
>>
>> >>> Foo() {
>> >>> cout << "Foo::Foo()" << endl;
>> >>> Foo( this->i );
>> >>> }
>>
>> >>> and prints:
>>
>> >>> Foo::Foo()
>> >>> Foo::Foo(int)
>> >>> Foo::~Foo()
>> >>> Foo::~Foo()
>>
>> >>> I have no idea, what difference the "this->" should make.
>>
>> >>> BTW: initializing i in the constructor does not help (although the
>> >>> program might have UB without doing so).
>>
>> >> This looks like a bug in gcc (4.3.0, in my case).
>>
>> > MSVC behaves the same way.
>>
>> I think that CockneyWinker has the solution in his posting:
>>
>> The problem is that the line Foo(i) is equivalent to Foo i, ...
>>
>> This seems to go against [5.2.3/1], but only if the line could not be parsed
>> as a declaration. By [6.8/1] it seems that is can.
>>
>> Best
>>
>> Kai-Uwe Bux
>
> Yes, It seems so. When I change Foo(i) to Foo((int)i) or Foo(2) then
> it behaves properly. But why does it need _extra_ typecast ? can't it
> see that _i_ is declared as an int ? I am sorry, I don't have much
> experience with C++. I still couldn't understand that how Foo(i) is
> equal to *Foo i* ?

Since you are allowed to declare a local variable with the same name as
a member the compiler interprets this as such. Why it is allowed I don't
know, but someone must have thought that it was good for something.

--
Erik Wikström

Bo Persson

10/19/2008 11:35:00 AM

0

Erik Wikström wrote:
> On 2008-10-19 12:18, Vijay Meena wrote:
>> On Oct 19, 2:05 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>>> Erik Wikström wrote:
>>>> On 2008-10-19 06:39, Sam wrote:
>>>>> Kai-Uwe Bux writes:
>>>
>>>>>> Vijay Meena wrote:
>>>
>>>>>>> Hi,
>>>>>>> This code is of no use. But I am just curious to know about
>>>>>>> what happening here.
>>>
>>>>>>> #include <iostream>
>>>>>>> using namespace std;
>>>
>>>>>>> class Foo {
>>>>>>> private:
>>>>>>> int i;
>>>>>>> public:
>>>>>>> Foo() {
>>>>>>> cout << "Foo::Foo()" << endl;
>>>>>>> Foo(i);
>>>>>>> }
>>>>>>> Foo(int i) : i(i) {
>>>>>>> cout << "Foo::Foo(int)" << endl;
>>>>>>> }
>>>>>>> ~Foo() {
>>>>>>> cout << "Foo::~Foo()" << endl;
>>>>>>> }
>>>>>>> };
>>>
>>>>>>> int main(int argc, char *argv[])
>>>>>>> {
>>>>>>> Foo();
>>>>>>> }
>>>
>>>>>>> I am getting infinite call to "Foo::Foo()". Program is not
>>>>>>> even executing "Foo::Foo(int)".
>>>
>>>>>> Hm, I am flabbergasted. The following _does_ the expected:
>>>
>>>>>> Foo() {
>>>>>> cout << "Foo::Foo()" << endl;
>>>>>> Foo( this->i );
>>>>>> }
>>>
>>>>>> and prints:
>>>
>>>>>> Foo::Foo()
>>>>>> Foo::Foo(int)
>>>>>> Foo::~Foo()
>>>>>> Foo::~Foo()
>>>
>>>>>> I have no idea, what difference the "this->" should make.
>>>
>>>>>> BTW: initializing i in the constructor does not help (although
>>>>>> the program might have UB without doing so).
>>>
>>>>> This looks like a bug in gcc (4.3.0, in my case).
>>>
>>>> MSVC behaves the same way.
>>>
>>> I think that CockneyWinker has the solution in his posting:
>>>
>>> The problem is that the line Foo(i) is equivalent to Foo i, ...
>>>
>>> This seems to go against [5.2.3/1], but only if the line could
>>> not be parsed as a declaration. By [6.8/1] it seems that is can.
>>>
>>> Best
>>>
>>> Kai-Uwe Bux
>>
>> Yes, It seems so. When I change Foo(i) to Foo((int)i) or Foo(2)
>> then it behaves properly. But why does it need _extra_ typecast ?
>> can't it see that _i_ is declared as an int ? I am sorry, I don't
>> have much experience with C++. I still couldn't understand that
>> how Foo(i) is equal to *Foo i* ?
>
> Since you are allowed to declare a local variable with the same
> name as a member the compiler interprets this as such. Why it is
> allowed I don't know, but someone must have thought that it was
> good for something.

Inner scopes are allowed to declare names also present in outer
scopes. Class members are no different from other scopes.

The fact that a set of parenthesis are allowed is just because
*sometimes* they are needed. There are just no rules about not using
them when not needed.

Also, if Foo(i) were to work as "expected", it would also create a
temporary Foo inside the constructor. This is also pretty useless (and
strictly UB, as the outer i is still uninitialized).


I guess that the OP really wants a "delegating constructor" which will
be available in the next standard, C++0x. A constructor will be able
to call another constructor of the same class, in its initializer
list:

Foo() : Foo(1)
{ }

will set i to 1. Foo(i) will till be bad though!



Bo Persson