Can some one please explain this code

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

    #1

    Can some one please explain this code

    # include <iostream>

    class A
    {
    public:
    A() : i(1) {} int i; } ;

    class B: public A
    {
    public :
    B(): j(2) {} int j ; } ;

    int f(A* p, int count)
    {
    int total = 0 ;
    for (int i=0; i < count ; ++i )
    { total += p->i; }

    return (total);
    }

    int main()
    {
    std::cout << f(b,10) <<std::endl;
    std::cin.get() ;
    return 0 ;
    }


    The output of the above code is 15. But, i expected 10?

    Thanks in advance to all..

  • Kai-Uwe Bux

    #2
    Re: Can some one please explain this code

    raghukumar wrote:
    # include <iostream>
    >
    class A
    {
    public:
    A() : i(1) {} int i; } ;
    >
    class B: public A
    {
    public :
    B(): j(2) {} int j ; } ;
    >
    int f(A* p, int count)
    {
    int total = 0 ;
    for (int i=0; i < count ; ++i )
    { total += p->i; }
    >
    return (total);
    }
    >
    int main()
    {
    std::cout << f(b,10) <<std::endl;
    std::cin.get() ;
    return 0 ;
    }
    >
    >
    The output of the above code is 15.
    Nope, the code does not compile because:

    std::cout << f(b,10) <<std::endl;
    ^

    The identifier b has no meaning.

    But, i expected 10?
    The obvious guess would be that the part of the code that you did not show
    has undefined behavior.


    Best

    Kai-Uwe Bux

    Comment

    • raghukumar

      #3
      Re: Can some one please explain this code

      On Nov 14, 9:53 am, raghukumar <raghukumar.r.. .@gmail.comwrot e:
      # include <iostream>
      >
      class A
      {
      public:
      A() : i(1) {} int i; } ;
      >
      class B: public A
      {
      public :
      B(): j(2) {} int j ; } ;
      >
      int f(A* p, int count)
      {
      int total = 0 ;
      for (int i=0; i < count ; ++i )
      { total += p->i; }
      >
      return (total);
      >
      }
      >
      int main()
      {
      std::cout << f(b,10) <<std::endl;
      std::cin.get() ;
      return 0 ;
      >
      }
      >
      The output of the above code is 15. But, i expected 10?
      >
      Thanks in advance to all..
      sorry friends..
      # include <iostream>

      class A
      {
      public:
      A() : i(1) {} int i; } ;

      class B: public A
      {
      public :
      B(): j(2) {} int j ; } ;

      int f(A* p, int count)
      {
      int total = 0 ;
      for (int i=0; i < count ; ++i )
      { total += p++->i; }

      return (total);

      }

      int main()
      {
      B b[10] ;
      std::cout << f(b,10) <<std::endl;
      std::cin.get() ;
      return 0 ;

      }


      The above is the full code.

      thanks ,

      Comment

      • Ian Collins

        #4
        Re: Can some one please explain this code

        raghukumar wrote:
        >
        int f(A* p, int count)
        {
        int total = 0 ;
        for (int i=0; i < count ; ++i )
        { total += p++->i; }
        >
        p is a pointer to A, p++ increments p by sizeof(A).
        return (total);
        >
        }
        >
        int main()
        {
        B b[10] ;
        std::cout << f(b,10) <<std::endl;
        You are passing an array of 10 Bs, a B is bigger than an A.

        --
        Ian Collins.

        Comment

        • raghukumar

          #5
          Re: Can some one please explain this code

          You are passing an array of 10 Bs, a B is bigger than an A.
          Hey i din't get this part, B is bigger than A agreed, but i am saying

          total += p++->i

          where i is member variable of A, initialized to 1.

          Comment

          • Joe Greer

            #6
            Re: Can some one please explain this code

            raghukumar <raghukumar.rag s@gmail.comwrot e in
            news:1195040164 .310279.262450@ v23g2000prn.goo glegroups.com:
            >
            >You are passing an array of 10 Bs, a B is bigger than an A.
            >
            Hey i din't get this part, B is bigger than A agreed, but i am saying
            >
            total += p++->i
            >
            where i is member variable of A, initialized to 1.
            >
            >
            When you increment a pointer, it behaves very much like it was
            performing
            (T *)((char *)p + sizeof(T)). The problem you have is that when you
            increment an A* it will add sizeof(A) to the pointer. Your array is of
            B's which have a different size than A. So to give a short example of
            what is happening. You have:

            0: 1
            1: 2
            2: 1
            3: 2

            and so on in memory. In this example, the size of A is 1 and the sizeof
            B is 2. Your function has no idea that Bs even exist (you pass it an
            A*) so as far it it's concerned you have an array of A's. The pointer
            will therefore visit the addresses 0, 0 + sizeof(A) = 1, 1 + sizeof(A) =
            2, 2 + sizeof(A) = 3 ... This is undefined behavior, but most compilers
            won't detect it as such and will happily give you whatever happens to be
            in the memory locations visited. In this case, you get 1, 2, 1, 2 ....
            And that results 5 1s and 5 2s giving 15. It is only because you only
            have the 2 integers in your classes that this isn't just a totally wacky
            value. Of course, your machine architecture with have different values
            for the sizeof an in and the addresses they exist in, but the behavior
            is the same.

            HTH
            joe

            Comment

            • raghukumar

              #7
              Re: Can some one please explain this code

              Hi,
              Your function has no idea that Bs even exist (you pass it an
              A*) so as far it it's concerned you have an array of A's. The pointer
              will therefore visit the addresses 0, 0 + sizeof(A) = 1, 1 + sizeof(A) =
              2, 2 + sizeof(A) = 3 ... This is undefined behavior, but most compilers
              won't detect it as such and will happily give you whatever happens to be
              in the memory locations visited. In this case, you get 1, 2, 1, 2 ....
              And that results 5 1s and 5 2s giving 15. It is only because you only
              have the 2 integers in your classes that this isn't just a totally wacky
              value. Of course, your machine architecture with have different values
              for the sizeof an in and the addresses they exist in, but the behavior
              is the same.
              I was thinking on the same line as mentioned above, and this is what i
              realized. Just for testing,
              i changed j variable's initial value to 3 in class B. Then ran the
              program, as you mentioned instead of getting 1,1,1,1 or 1,2,1,2, it
              gave 1,3,1,3(sum=20) . This indicates to me that the value which i am
              getting as an output, which is 20, is completely depend on how the
              internal class structure is stored in memory. But, i don't know what
              does standard say anything about this. So, this means can i assume
              this behavior is not undefined, as any one at given point in time can
              detect the value of the output. If it's really has undefined
              behavior, can somebody please show me the right direction, so that i
              can get some proof(code), which makes me believe.

              Thanks for all your guidance,


              Comment

              • werasm

                #8
                Re: Can some one please explain this code

                On Nov 14, 6:03 pm, raghukumar <raghukumar.r.. .@gmail.comwrot e:
                If it's really has undefined
                behavior, can somebody please show me the right direction, so that i
                can get some proof(code), which makes me believe.
                >
                Thanks for all your guidance,
                If you want to use pointer arithmetic, you are bounded
                to the actual (base) type. Therefore if you define
                an array of B's, the next item is not at (A+1), but
                at (B+1). Therefore (A+1) would send you to who knows
                where. To prove this, simply change the array to
                an array of real A's, otherwise don't use pointer
                arithmetic for the traversal (dangerous!).

                Code below would give you the correct result.

                #include <iostream>

                class A
                {
                public:
                A() : i(1) {}
                int i;
                };

                class B : public A
                {
                public :
                B(): j(2)
                {}
                int j;
                };

                int f(A* p, int count)
                {
                int total = 0 ;
                for (int i=0; i < count ; ++i )
                {
                total += p++->i;
                }
                return (total);
                }

                int main()
                {
                A a[10];
                std::cout << f(a,10) << std::endl;
                std::cin.get() ;
                return 0 ;
                }

                Comment

                • Joe Greer

                  #9
                  Re: Can some one please explain this code

                  raghukumar <raghukumar.rag s@gmail.comwrot e in news:1195059799 .037952.79770
                  @t8g2000prg.goo glegroups.com:
                  >
                  I was thinking on the same line as mentioned above, and this is what i
                  realized. Just for testing,
                  i changed j variable's initial value to 3 in class B. Then ran the
                  program, as you mentioned instead of getting 1,1,1,1 or 1,2,1,2, it
                  gave 1,3,1,3(sum=20) . This indicates to me that the value which i am
                  getting as an output, which is 20, is completely depend on how the
                  internal class structure is stored in memory. But, i don't know what
                  does standard say anything about this. So, this means can i assume
                  this behavior is not undefined, as any one at given point in time can
                  detect the value of the output. If it's really has undefined
                  behavior, can somebody please show me the right direction, so that i
                  can get some proof(code), which makes me believe.
                  >
                  The standard says this is undefined behavior. The object layout is compiler
                  dependent and there is no guarantees about much of anything. It just happens
                  give something sensible in your case.

                  Well, if you want proof that what you are doing is a bad idea, change your j
                  variable to a double with the value of 30000 and then see what you get.

                  What you need to do is iterate through B's and that will give you the right answer.
                  QED.

                  joe

                  Comment

                  • Tadeusz B. Kopec

                    #10
                    Re: Can some one please explain this code

                    On Wed, 14 Nov 2007 11:36:04 +0000, raghukumar wrote:
                    >You are passing an array of 10 Bs, a B is bigger than an A.
                    >
                    Hey i din't get this part, B is bigger than A agreed, but i am saying
                    >
                    total += p++->i
                    >
                    where i is member variable of A, initialized to 1.
                    Effect of expression p++, where p is of type A * may be:
                    1) If p points to an element of array of type A - p will point to next
                    element of this array (or past the end if before p pointed to the last
                    element)
                    2) In any other case it has undefined behaviour.

                    In your code p doesn't point to an array of A (it's an array of B), so
                    you have undefined behaviour.

                    --
                    Tadeusz B. Kopec (tkopec@NOSPAMP LEASElife.pl)
                    Blinding speed can compensate for a lot of deficiencies.
                    -- David Nichols

                    Comment

                    • raghukumar

                      #11
                      Re: Can some one please explain this code

                      Hi All,

                      Well Thanks for your answers, but you know what this question is asked
                      as one of interview questions, and output was given as 10,15,200,150.
                      There was no answer which says, undefined behavior, for the first
                      moment even i had the same impression, but to them what matters is
                      whether your answer is right/wrong. But any how, this was good
                      learning point for me.

                      Thanks,

                      Regards,
                      Raghu Kumar K

                      Comment

                      • werasm

                        #12
                        Re: Can some one please explain this code

                        On Nov 16, 6:44 pm, raghukumar <raghukumar.r.. .@gmail.comwrot e:
                        Well Thanks for your answers, but you know what this question is asked
                        as one of interview questions, and output was given as 10,15,200,150.
                        There was no answer which says, undefined behavior, for the first
                        moment even i had the same impression, but to them what matters is
                        whether your answer is right/wrong.
                        What about - "none of the above". If this was not option, then
                        the questionnaire was flawed.

                        Werner

                        Comment

                        • raghukumar

                          #13
                          Re: Can some one please explain this code

                          What about - "none of the above". If this was not option, then
                          the questionnaire was flawed.
                          Well, nothing like this was mentioned. ... :)
                          only four options..

                          Thanks,

                          Comment

                          Working...