written 7.0 years ago by | modified 2.9 years ago by |
Subject: system programming and compiler construction
Topic: Macros & Macro processors
Difficulty: Low
written 7.0 years ago by | modified 2.9 years ago by |
Subject: system programming and compiler construction
Topic: Macros & Macro processors
Difficulty: Low
written 6.9 years ago by |
The two most common methods for parameter passing in modern imperative languages are call by value and call by reference. Call by name is primarily of historical interest, but is closely related to the way that parameters are handled when macros are expanded, and has the same semantics as lazy evaluation in functional languages. Languages with input/output parameters support call by value-result which differs subtly from call by reference Techniques used for argument passing in traditional imperative languages: • call by value • call by result • call by value-result • call by reference • call by name • call by value: copy going into the procedure. This is the mechanism used by both C and Java. Note that this mechanism is used for passing objects, where a reference to the objected is passed by value. • call by result: copy going out of the procedure, the formal parameters are copied back into the actual parameters. (Note that this only makes sense if the actual parameter is a variable, or has a l-value, such as an array element.) • call by value result: copy going in, and again going out • call by reference: The actual parameters and formal parameters are identified. The natural mechanism for this is to pass a pointer to the actual parameter, and indirect through the pointer • call by name: re-evaluate the actual parameter on every use. For actual parameters that are simple variables, this is the same as call by reference. For actual parameters that are expressions, the expression is re-evaluated on each access. It should be a run time error to assign into a formal parameter passed by name, if the actual parameter is an expression. Implementation: use anonymous function ("thunk") for call by name expressions • Call by value is particularly efficient for small pieces of data (such integers), since they are trivial to copy, and since access to the formal parameter can be done efficiently. • Call by reference is particularly efficient for large pieces of data (such as large arrays), since they don't need to be copied. Call by reference also allows a procedure to manipulate the values of variables of the caller, such as in a swap routine.