Query with constructor calls

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Vijay Meena

    #1

    Query with constructor calls

    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(i nt)" << 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

  • Kai-Uwe Bux

    #2
    Re: Query with constructor calls

    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(i nt)" << 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

    Comment

    • Sam

      #3
      Re: Query with constructor calls

      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(i nt)" << 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().



      -----BEGIN PGP SIGNATURE-----
      Version: GnuPG v1.4.9 (GNU/Linux)

      iEYEABECAAYFAkj 6ufEACgkQx9p3GY HlUOK+qACdFG4hs TUFnjOplpkCJfQQ YkeO
      m1wAn0sgSHrh78c Ui1IK+NFFFvNFFt Fl
      =qVU9
      -----END PGP SIGNATURE-----

      Comment

      • ebony.soft@gmail.com

        #4
        Re: Query with constructor calls

        On Oct 19, 6:32 am, Vijay Meena <vijay.me...@gm ail.comwrote:
        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(i nt)" << 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:


        Regards,
        Saeed Amrollahi


        Comment

        • CockneyWinker

          #5
          Re: Query with constructor calls


          "Vijay Meena" <vijay.meena@gm ail.comwrote in message
          news:a72193b7-f0d2-4209-a86e-d0d1529ac1be@79 g2000hsk.google groups.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(i nt)" << 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;

          }




          Comment

          • CockneyWinker

            #6
            Re: Query with constructor calls


            "Vijay Meena" <vijay.meena@gm ail.comwrote in message
            news:a72193b7-f0d2-4209-a86e-d0d1529ac1be@79 g2000hsk.google groups.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(i nt)" << 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.


            Comment

            • =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=

              #7
              Re: Query with constructor calls

              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(i nt)" << 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

              Comment

              • Kai-Uwe Bux

                #8
                Re: Query with constructor calls

                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(i nt)" << 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

                Comment

                • Vijay Meena

                  #9
                  Re: Query with constructor calls

                  On Oct 19, 2:05 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                  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(i nt)" << 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* ?

                  Comment

                  • =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=

                    #10
                    Re: Query with constructor calls

                    On 2008-10-19 12:18, Vijay Meena wrote:
                    On Oct 19, 2:05 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                    >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(i nt)" << 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

                    Comment

                    • Bo Persson

                      #11
                      Re: Query with constructor calls

                      Erik Wikström wrote:
                      On 2008-10-19 12:18, Vijay Meena wrote:
                      >On Oct 19, 2:05 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                      >>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.
                      >>>
                      >>>>>>#includ e <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(i nt)" << 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



                      Comment

                      • James Kanze

                        #12
                        Re: Query with constructor calls

                        On Oct 19, 5:55 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                        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(i nt)" << 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.

                        --
                        James Kanze (GABI Software) email:james.kan ze@gmail.com
                        Conseils en informatique orientée objet/
                        Beratung in objektorientier ter Datenverarbeitu ng
                        9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                        Comment

                        Working...