Query with constructor calls

V

Vijay Meena

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
 
K

Kai-Uwe Bux

Vijay said:
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
 
E

Erik Wikström

Kai-Uwe Bux said:
Vijay said:
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.
 
K

Kai-Uwe Bux

Erik said:
Kai-Uwe Bux said:
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
 
V

Vijay Meena

Erik said:
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* ?
 
E

Erik Wikström

Erik said:
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:

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.
 
B

Bo Persson

Erik said:
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
 
J

James Kanze

Vijay Meena wrote:
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.

It changes a variable definition ("Foo (i);", which is exactly
the same thing as if he'd written "Foo i;") into a type
conversion expression (since "this->i" isn't a legal variable
name, nor can it possibly be parsed as part of a variable
declaration).

Just another variant of C++'s most embarassing parse.
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,588
Members
45,094
Latest member
PollyBlau4

Latest Threads

Top