-2

Here is the code.

#include <iostream>

using namespace std;

int w=0;

class A{
  int k,n;
 public:
  int z;
  A(){w+=3; k=3+w; n=4+w; z=w;}
  A *fun1(){z=k*n; return this;}
  A *fun2(){z=n*k; return this-1;}
  friend int fun (A *a,int &b);
};

int fun(A *a,int &b)
{ b=a->z+=4;
  return a->k+a->n;
}

int main()
{ int m;
  A a[2];
  cout<<fun(a[1].fun1(),m)<<"\n";
  cout<<m<<"\n";
  cout<<fun(a[1].fun2(),m)<<"\n";
  cout<<m<<"\n";
  cout<<a[0].z+a[1].z<<"\n";
  return 0;
}

When return this-1 happens, what does it mean? Does it mean that the object returned is a[0]? I can't understand.. Thanks!

mitsoschelsea
  • 23
  • 2
  • 7
  • Yes, when you call `a[1].fun2()` then `return this-1;` is indeed `a[0]`. Indeed `this` here refers to `a[1]` and `A a[2];` declares a contiguous array in memory of `A` elements. – coincoin Sep 07 '15 at 07:53
  • then what if I give `a[0]` and then `return this-1`? the value in return will be the value of the memory? – mitsoschelsea Sep 07 '15 at 08:09
  • You will exceed the array size, so the behavior is undefined. – Estiny Sep 07 '15 at 08:12

2 Answers2

3

Like any pointer, subtracting 1 from this assumes *this is an element of an array, gives the address of the preceding object in the array. There is an implicit assumption in A::fun2() that *this is an element of an array, and that there is at least one preceding element in that array.

So, in your sample code, a[1].fun2() returns the the address of a[0]. i.e. &a[0].

a[0].fun2() would return a (pointer) value equal to &a[-1]. Notionally, that is a pointer to a non-existent object. Computing this-1 in A::fun2() would give undefined behaviour just as much as computing a-1 would in main(). One common (but not guaranteed) practical symptom of such undefined behaviour would be a program crashing when later dereferencing the pointer.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • Actually, I believe that subtracting one from a pointer to the beginning of an array is actually undefined behavior. (unless that array is part of a larger object, of course) –  Sep 07 '15 at 08:20
  • Why would it be? You're just subtracting from a value, not accessing any memory. – Emil Laine Sep 07 '15 at 08:22
  • 3
    Ah, here we go under Additive Operators `[expr.add]`: `If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.` –  Sep 07 '15 at 08:24
  • Peter is correct. Subtracting itself won't cause Undefined Behavior. Only dereferencing the pointer causes it. [Here](http://stackoverflow.com/questions/1239938/c-accesses-an-array-out-of-bounds-gives-no-error-why) is nice explanation. – Estiny Sep 07 '15 at 08:27
  • Hurkl is actually correct. I omitted to say anything about whether the subtraction gives defined or undefined behaviour, mainly because - in my experience - explaining such things is more likely to confuse rather help beginners. I simply said that the function assumes some things, but didn't say that the behaviour is undefined if those assumptions are violated. I've adjusted my wording slightly to reflect this - the result will be more technically correct, but include more subtleties to trip beginners. – Peter Sep 07 '15 at 09:03
-3

A fun2(){z=nk; return this-1;}

'this' is a self-referential pointer. You cannot subtract 1 from this. It will then point to a memory location which is one before 'this' pointer

Rishav Raj
  • 11
  • 2