To make sure everybody understands the differences between the different argument passing mechanisms, it would be valuable for us to write procedures that produce different results depending on whether their arguments are passed by value, by reference, by value-result, or by name. (As an aside, these are often known as "call by value," "call by reference," etc., even though the procedure calling per se is the same in each case; the difference is in the passing of arguments.)
The definition of passing an argument by name needs to be more careful than the one Tucker and Noonan give. If the actual concrete syntax were copied in, lexical scoping would be violated. Consider the following example:
void foo(int x){ x = x + 1; } void main(){ int a = 10; foo(a); print(a); }
Suppose that the call foo(a)
passed its argument by
name. If this were literally done by substitution, the assignment
statement in foo
would become a = a + 1;
,
which isn't legal, because it is outside the scope of a
.
If foo
were changed to have its own local variable
a
, then the assignment statement would be legal, but it
would be changing foo
's a
, rather than
main
's. This is not what call-by-name does.
All names remain interpreted in their original environment, so that in
this case main
's a
would increase from 10 to
11 before being printed.
As this example illustrates, call-by-name can sometimes seem to be the same as call-by-reference. This has an interesting tie-in with the history of call-by-name. This argument passing technique originated in Algol 60. The original plan of the Algol 60 committee had been for call-by-reference and call-by-value to be the two options, rather than call-by-name and call-by-value. To the very end, some members of the committee preferred call-by-reference, but they were having difficulty formulating a simple, correct specification of it. Other committee members put forward a specification of call-by-name as an alternative, on the last day of the committee meeting. It isn't clear whether everyone understood that what was being suggested was a different parameter passing mechanism, rather than just a different specification of call-by-reference. The proposal was adopted, in the last hour of the last day, but according to Peter Naur, "it seemingly was understood in a coherent manner only by one member, Alan Perlis." ("The European Side of the Last Phase of the Development of Algol 60," in History of Programming Languages, Richard L. Wexelblat, ed., Academic Press, 1991, pp. 111-112.)
To fully understand the example of how pointers are used in C, there are a couple items that might be worth our discussing. You need to understand the difference between
struct Foo { int a; struct Bar b; }; struct Bar { int c; int d; }
and
struct Foo { int a; struct Bar *b; }; struct Bar { int c; int d; }
Also, you need to understand that p->x
means the
same thing as (*p).x
; both refer the the field named
x
within the structure that the pointer p
points to.