Phantasmal MUD Lib for DGD

Phantasmal Site > DGD > DGD Reference Manual (legacy) > Arguments and Call-By-Value

3.11 Arguments and Call-By-Value

In LPC, most values are passed by value. That means if you pass an integer variable with a value of 3 into a function and you change that variable in the function, the variable doesn't change outside the function. Because of that, the following code doesn't do what it looks like it's supposed to. In fact, it does nothing.

/* Swap two integers */
void swap(int a, int b) {
  int tmp;
  tmp = b;
  b = a;
  a = b;
}

It doesn't swap the values beyond the end of the function. Internally, LPC makes the new variables for arguments a and b and copies the values in. The code swaps the values of the arguments' LPC-internal variables, but those variables are going to disappear at the end of the function. This method of function call is named call-by-value because only the value gets passed in -- the original variable is copied so the function never sees it.

LPC passes arrays, mappings and objects by reference. That means that if you change an element in the array, it's changed everywhere, not just in that one function. So call-by-value is only used for integers, floating-point numbers and strings. Values of type mixed are passed according to the underlying type — a mixed variable with a current value of 3 or nil will be passed by value, while one whose current value is a mapping will be passed by reference, and might be modified.

The fact that some objects are passed by reference has security implications. If an object in your application keeps information on all users, it will probably wish to use an array or mapping. It may wish to have a query function to return such an array or mapping to a caller, or it may wish to call functions in other objects with a list of users. But if it simply passes its array or mapping around as an argument, then other objects may modify that array or mapping, which would be highly inconvenient. Instead, the object should copy the array or mapping before returning it, and before passing it as an argument to any questionably-trusted functions. The copied array or mapping contains all the same information, but will not change the original if it is modified. For example:

void trusted_function(void) {
  mixed *users;
  mixed *copied_users;

  users = "/usr/System/sys/secured"->get_user_array();

  copied_users = users[..];  /* Make a copy */
  untrusted_function(7, "sam", copied_users);
}
<— Prev
Objects
Up
A Quick LPC Tutorial
Next —>
External Variables and Scope