How does c++ by-ref argument passing is compiled in assembly?

By : Anzurio
Source: Stackoverflow.com
Question!

In the late years of college, I had a course on Compilers. We created a compiler for a subset of C. I have always wondered how a pass-by-ref function call is compiled into assembly in C++.

For what I remember, a pass-by-val function call follows the following procedure:

  • Store the address of the PP
  • Push the arguments onto the stack
  • Perform the function call
  • In the function, pop from stack the parameters

What's different for pass-by-reference? (int void(int&);)

EDIT:

I may sound totally lost but, if you could help me I'd really appreciate it.

Everyone's answer is basically that it passes the address instead of the value. I understood that to be basically what passing a pointer is. So how come, these two functions, behave differently?:

struct A {
    int x;
    A(int v){
        x = v;
    }
};

int byRef(A& v){
    v = A(3);
    return 0;
}

int byP   (A* v){
    v = &A(4); //OR new A(4)
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    A a (1); A b (2);
    byRef(a); byP  (&b);
    cout << a.x << " " << b.x;

    system("pause");

    return 0;
}

I know that in byP(A*), v is being passed by value, thus, it won't affect the caller's argument. Then, how would you implement byRef(A&) in terms of A*?

By : Anzurio


Answers
int byRef(A& v){
  v = A(3);
  return 0;
}

This invokes the assignment of the temporary object to the object passed by reference, the object used in the function call is modified. A shallow copy will be performed if no assignment operator is provided.

int byP   (A* v){
  v = &A(4); //OR new A(4)
  return 0;
}

This copies a pointer to a temporary object to the passed in pointer value. No assignment function is called. The value of 'v' is changed but the object v pointed to, the object address passed as an argument, is unchanged.

If you did this:

struct A {
  int x;
  A(int v){
    x = v;
  }
  A &operator = (A &rhs){
    cout << "assignment!";
  }
};

then the "assignment" will be output in the byRef function but not the byP function.

Although the & is implemented using pointers 'under the hood', as others have said, they are treated as the object passed to the function by the language.

So, to implement the byRef using pointers:

int byRefUsingP (A *v)
{
  *v = A(3);
  // or you could do:
  // v->operator = (A(3));
  // if an operator = is defined (don't know if it will work without one defined)
  return 0;
}
By : Skizz


When passing by value, the compiler emits code to do a bitwise copy of the source bytes to the destination variable. For large structures and/or frequent assignments this can get quite inefficient. If your struct overrides the assignment operator, it will be called instead, and then you have control over what gets copied, but you're still pushing the whole structure on the stack.

When passing by reference the address of the struct gets pushed onto the stack, which is just an int. This is the most efficient way to pass large objects.

When passing by pointer the address of the pointer gets pushed on the stack. The pointer has to be dereferenced to get the address of the struct. There is an extra operation involved.

BTW, there is a serious bug in the byP function: it is assigning a temporary local variable to a pointer. The struct is allocated on the stack, and will (very likely) be overwritten after it goes out of scope. You must use "new" to allocate it on the heap, or assign the struct to the value referenced by the pointer, as per Neil Butterworth's example.

By : alekop


This video can help you solving your question :)
By: admin