Home > front end >  Confusing output with respect to addresses when passing object by reference in C
Confusing output with respect to addresses when passing object by reference in C

Time:01-10

the following code from the turorial http://www.cplusplus.com/doc/tutorial/ :

// example on this
#include <iostream>
using namespace std;

class Dummy {
public:
  bool isitme (Dummy& param);
};

bool Dummy::isitme (Dummy& param)
{
  //cout << param << endl;//this cant be printed with cout ?!
  printf("TEST3: param=%p\n",param);
  cout << "TEST4: &param=" << &param << endl;
  if (&param == this) return true;
  else return false;
}

int main () {
  Dummy a;
  Dummy* b = &a;
  cout << "TEST1: &a=" << &a << endl;
  printf("TEST2: a=%p\n",a);
  if ( b->isitme(a) )
    cout << "yes, &a is b\n";
  return 0;
}

which whith the added "TESTS" to show addresses give me the output:

TEST1: &a=0x7ffc9bdea7bf
TEST2: a=(nil)
TEST3: param=0x7ffc9bdea7bf
TEST4: &param=0x7ffc9bdea7bf
yes, &a is b

This is very confusing for me since - as far as I understand - with the pass by reference way of passing args to functions, i.e., as it is done for the "isitme" member function, when we pass an argument to it, this arg is "magically" dereferenced in the body of the function and should not contain the address of the variable (but somehow the address is "magically" i.e. automatically used to access the actual contents of course so as to modify the variable outside the function). But please clarify any inconsistencies that I might have said...

So three questions:

  1. what exactly is a? is it a pointer to the first byte of the object a in memory... it it something else... it is not clear what exactly is in a. (it does not seem to be a pointer since there is the other syntax with Dummy* a = new Dummy... but what else could it be?)

  2. why does TEST2 output (nil) (nil on my local machine after compilation, and in the online REPL it actually outputs a DIFFERENT address than all the others) ?

  3. Why does TEST3 and TEST4 give the same value for param and &param ?! (it is like if the address of "param" and the contents of "param" are the same... this is totally confusing but I suspect it has to do with the pass-by-ref "magic"?) I thought param as passed by ref would be automatically dereferenced...

P.S. Although the cpp tutorial is nice, I think they should spend a lot more time explaining this in at least a full paragraph to explain all that behavior which is not obvious at all.

http://cpp.sh/6hlpok

https://cplusplus.com/doc/tutorial/templates/

CodePudding user response:

Ok, I think doing this clarifies things for me:

// example on this
#include <iostream>
using namespace std;

class Dummy {

public:
  int x;
  int y;
  Dummy(int a,int b){x=a;y=b;};
  bool isitme (Dummy& param);
};

bool Dummy::isitme (Dummy& param)
{
  printf("x=%d\n", param.x);
  //cout << param << endl;//this cant be printed with cout ?!
  printf("TEST4: param=%p\n",param);
  cout << "TEST5: &param=" << &param << endl;
  if (&param == this) return true;
  else return false;
}

int main () {
  Dummy a(5,6);
  Dummy* b = &a;
  cout << "TEST1: &a=" << &a << endl;
  printf("TEST2: a=%p\n",a);
  printf("TEST3: &a = %p \n",&a);
  if ( b->isitme(a) )
    cout << "yes, &a is b\n";
  return 0;
}

the output is then:

TEST1: &a=0x7ffca1f51280
TEST2: a=0x600000005
TEST3: &a = 0x7ffca1f51280
x=5
TEST4: param=0x600000005
TEST5: &param=0x7ffca1f51280
yes, &a is b

and now in fact I see that "param" is the raw memory occupied by the data i.e., TEST4: a=0x600000005 , i.e. values 5 and 6 , in the object it seems!

CodePudding user response:

It works as expected if you pass the addresses to the printfs:

#include <iostream>
using namespace std;

class Dummy {
public:
  bool isitme (Dummy& param);
};

bool Dummy::isitme (Dummy& param)
{
  //cout << param << endl;//this cant be printed with cout ?!
  printf("TEST3: &param=%p\n", &param);
  cout << "TEST4: &param=" << &param << endl;
  if (&param == this) return true;
  else return false;
}

int main () {
  Dummy a;
  Dummy* b = &a;
  cout << "TEST1: &a=" << &a << endl;
  printf("TEST2: &a=%p\n", &a);
  if ( b->isitme(a) )
    cout << "yes, &a is b\n";
  return 0;
}
TEST1: &a=0x7ffc9dd881df
TEST2: a=0x7ffc9dd881df
TEST3: param=0x7ffc9dd881df
TEST4: &param=0x7ffc9dd881df
yes, &a is b
  •  Tags:  
  • Related