Const ref

what is the use of “const ref” ? and why we write const ref together always ?

In reply to Hardik Trivedi:

In reply to Hardik Trivedi:
You first have to understand that by default, most task/function (routine) arguments are inputs copied by value. That means if you pass a variable to a task/function (the actual argument), the value of that variable is copied to a local variable upon entry to that routine (the formal argument). You can modify the formal argument, but the actual argument will never change, even after you return from the routine.
The reverse is true for an output argument. Upon entry to the routine, there is no change to the formal argument, but once inside, you can modify the formal, and the value of the formal argument gets copied to the actual argument. SystemVerilog also has an inout argument that copies the actual to the formal upon entry, and then copies the formal to actual upon return from the routine. A key point about copy by value, is that there is only one copy in, and and one copy out. If you have a time consuming task, the actual and formal arguments are not synchronized except upon entry and return from the routine.

A ref argument is always synchronized because you are passing a reference to the actual argument. When you refer to the formal argument inside your routine, you are referencing the actual argument, not a local variable. Another reason people use a ref argument is for performance instead of passing a large structure or an array when only a small number of elements need to be accessed. Most compilers do this automatically as an optimization, so this is usually not needed.

Finally, to get to your original question, a const ref argument behaves the same as a ref argument, except that the compiler will treat the formal argument as read-only. There are a number of situations that require functions to have no side-effects (no modification of variables outside of the function except through the return value). So the LRM restricts functions in this situation to only having input or const ref arguments.

Note that you almost never need to pass a class variable or virtual interface variable by reference since the handle is already a reference to an object. And a const ref argument of this type will only prevent you from changing the handle to point to another object. It will not prevent you from writing to a member of the class object.

In reply to dave_59:

In reply to Hardik Trivedi:
You first have to understand that by default, most task/function (routine) arguments are inputs copied by value. That means if you pass a variable to a task/function (the actual argument), the value of that variable is copied to a local variable upon entry to that routine (the formal argument). You can modify the formal argument, but the actual argument will never change, even after you return from the routine.
The reverse is true for an output argument. Upon entry to the routine, there is no change to the formal argument, but once inside, you can modify the formal, and the value of the formal argument gets copied to the actual argument. SystemVerilog also has an inout argument that copies the actual to the formal upon entry, and then copies the formal to actual upon return from the routine. A key point about copy by value, is that there is only one copy in, and and one copy out. If you have a time consuming task, the actual and formal arguments are not synchronized except upon entry and return from the routine.
A ref argument is always synchronized because you are passing a reference to the actual argument. When you refer to the formal argument inside your routine, you are referencing the actual argument, not a local variable. Another reason people use a ref argument is for performance instead of passing a large structure or an array when only a small number of elements need to be accessed. Most compilers do this automatically as an optimization, so this is usually not needed.
Finally, to get to your original question, a const ref argument behaves the same as a ref argument, except that the compiler will treat the formal argument as read-only. There are a number of situations that require functions to have no side-effects (no modification of variables outside of the function except through the return value). So the LRM restricts functions in this situation to only having input or const ref arguments.
Note that you almost never need to pass a class variable or virtual interface variable by reference since the handle is already a reference to an object. And a const ref argument of this type will only prevent you from changing the handle to point to another object. It will not prevent you from writing to a member of the class object.

Hi Dave,

Thanks a lot for the beautiful explanation. I have one question on ref.
Can ref used for passing the class objects handles like what we refer it has pointers in C++?.
Could you give some examples if possible where we use ref to pass class objects pointer/handler?.
Until now i never used ref for passing any class objects so, curious to know when, where and how to use this pass by reference method for the class objects.

In reply to chethan2807:

If you pass a class variable by ref, you now have a reference to a variable that holds a reference to class object—a double reference.

The only time you might need to do this is if you need change the object being referenced while the task was active.

Hi Dave,

What could be the use case of const ref , because if we do not want the variable to be changed we can use pass by value method instead of pass by reference.

Regards,
Saket