gawk: Pass By Value/Reference

 
 9.2.3.3 Passing Function Arguments by Value Or by Reference
 ...........................................................
 
 In 'awk', when you declare a function, there is no way to declare
 explicitly whether the arguments are passed "by value" or "by
 reference".
 
    Instead, the passing convention is determined at runtime when the
 function is called, according to the following rule: if the argument is
 an array variable, then it is passed by reference.  Otherwise, the
 argument is passed by value.
 
    Passing an argument by value means that when a function is called, it
 is given a _copy_ of the value of this argument.  The caller may use a
 variable as the expression for the argument, but the called function
 does not know this--it only knows what value the argument had.  For
 example, if you write the following code:
 
      foo = "bar"
      z = myfunc(foo)
 
 then you should not think of the argument to 'myfunc()' as being "the
 variable 'foo'."  Instead, think of the argument as the string value
 '"bar"'.  If the function 'myfunc()' alters the values of its local
 variables, this has no effect on any other variables.  Thus, if
 'myfunc()' does this:
 
      function myfunc(str)
      {
         print str
         str = "zzz"
         print str
      }
 
 to change its first argument variable 'str', it does _not_ change the
 value of 'foo' in the caller.  The role of 'foo' in calling 'myfunc()'
 ended when its value ('"bar"') was computed.  If 'str' also exists
 outside of 'myfunc()', the function body cannot alter this outer value,
 because it is shadowed during the execution of 'myfunc()' and cannot be
 seen or changed from there.
 
    However, when arrays are the parameters to functions, they are _not_
 copied.  Instead, the array itself is made available for direct
 manipulation by the function.  This is usually termed "call by
 reference".  Changes made to an array parameter inside the body of a
 function _are_ visible outside that function.
 
      NOTE: Changing an array parameter inside a function can be very
      dangerous if you do not watch what you are doing.  For example:
 
           function changeit(array, ind, nvalue)
           {
                array[ind] = nvalue
           }
 
           BEGIN {
               a[1] = 1; a[2] = 2; a[3] = 3
               changeit(a, 2, "two")
               printf "a[1] = %s, a[2] = %s, a[3] = %s\n",
                       a[1], a[2], a[3]
           }
 
      prints 'a[1] = 1, a[2] = two, a[3] = 3', because 'changeit()'
      stores '"two"' in the second element of 'a'.
 
    Some 'awk' implementations allow you to call a function that has not
 been defined.  They only report a problem at runtime, when the program
 actually tries to call the function.  For example:
 
      BEGIN {
          if (0)
              foo()
          else
              bar()
      }
      function bar() { ... }
      # note that `foo' is not defined
 
 Because the 'if' statement will never be true, it is not really a
 problem that 'foo()' has not been defined.  Usually, though, it is a
 problem if a program calls an undefined function.
 
    If '--lint' is specified (SeeOptions), 'gawk' reports calls to
 undefined functions.
 
    Some 'awk' implementations generate a runtime error if you use either
 the 'next' statement or the 'nextfile' statement (SeeNext
 Statement, and SeeNextfile Statement) inside a user-defined
 function.  'gawk' does not have this limitation.