How is the C ++ by-ref argument compiled in the assembly?

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

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

  • Keep PP address
  • Paste the arguments onto the stack
  • Make a function call
  • In the function pop from the stack parameters

What is the difference in bandwidth? (int void (int &);)

EDIT:

I may seem completely lost, but if you could help me, I would really appreciate it.

Each answer basically consists in passing an address instead of a value. I realized that this is basically what the pointer passes. So, how do 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 << ax << " " << bx; system("pause"); return 0; } 

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

+4
source share
8 answers
 int byRef(A& v){ v = A(3); return 0; } 

This causes the temporary object to be assigned to the object passed by reference, the object used in the function call changes. A shallow copy will be executed if no assignment operator is assigned.

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

This copies the pointer to a temporary object to the passed value of the pointer. The destination function is called. The value of 'v' changes, but object v indicates that the address of the object passed as an argument does not change.

If you have done this:

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

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

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

So, to implement byRef with 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; } 
+4
source

You pass a pointer to a referand, just like any other pointer, and the caller knows how to use it. Depending on the implementation, this may not be on the stack β€” some parameters are passed in registers in some calling conventions.

There may be other ways to do this, since the C ++ standard does not indicate how afaik links are used, and even if they are implemented as pointers, I believe that they can be highlighted in the calling convention. However, pointers are the most obvious implementation.

+6
source

A link call will include passing a pointer to the value, not a copy of the value itself. If you are interested in the details of gory, you can get your compiler to emit assembly language and learn it yourself.

Edit: An example of your pointer should be:

 int byP (A* v) { * v = A(4); // modify thing referenced by the pointer return 0; } 
+4
source

The difference is that it passes the address of the parameter, not the value of the parameter.

0
source

I did not consider something like a GCC implementation, but the general idea is that instead of passing the contents of a variable, you pass its address (as if the C ++ code used "*" instead of "&" for the parameter).

Other schemes are available, but this is usually done by pushing the values ​​(or addresses) on the stack.

0
source

I think that in pass-by-val the procedure will be: * Save the PP value * Paste the arguments onto the stack * Make a function call * In the function pop from the stack, parameters

and in pass-by-ref the procedure will be the one you wrote

amuses

0
source

You could search for yourself. Many debuggers allow you to switch between code representation and disassembly. I would set a breakpoint in the function call in the code view, run the application at that point, switch to assembly and step over each command.

[SPOILER ALERT]

.

This is a pointer.

0
source

When passed by value, the compiler emits code for a bitwise copy of the source bytes of the target variable. For large structures and / or frequent assignments, this can become quite inefficient. If your structure overrides the assignment operator, it will be called instead, and then you will control what is copied, but you still click on the entire structure on the stack.

When passed by reference, the address of the structure gets on the stack, which is just int. This is the most efficient way to transfer large objects.

When passing through a pointer, the address of the pointer gets on the stack. The pointer must be dereferenced to get the address of the structure. There is an additional operation.

By the way, there is a serious error in the byP function: it assigns a temporary local variable to the pointer. The structure is allocated on the stack and will most likely be overwritten after leaving the area. You must use the β€œnew” to highlight it on the heap, or assign the structure the value that the pointer points to, according to Neil Butterworth's example.

0
source

All Articles