3.5 Example 4

  6619 getf (f)
       {
         register *fp, rf;
         rf = f;
         if (rf < 0 || rf >= NOFILE)
           goto bad;
         fp = u.u_ofile[rf];
         if (fp != NULL)
         return (fp);
       bad:
         u.u_error = EBADF;
         return (NULL);
       }

The parameter “f” is a presumed integer, and is copied directly into the register variable “rf”. (This pattern will become so familiar that we will now cease to remark upon it.)

The three simple relational expressions

  rf < 0    rf >=NOFILE    fp != NULL

are each accorded the value one if true, and the value zero if false. The first tests if the value of “rf” is less than zero, the second, if “rf” is greater than the value defined by “NOFILE” and the third, if the value of “fp” is not equal to “NULL” (which is defined to be zero).

The conditions tested by the “if” statements are the arithmetic expressions contained within parentheses.

If the expression is greater than zero the test is successful and the following statement is executed. Thus if for instance, “fp” had the value 001375, then

    fp != NULL

is true, and as a term in an arithmetic expression, is accorded the value one. This value is greater than zero, and hence the statement

    return(fp);

would be executed, to terminate further execution of “getf”, and to return the value of “fp” to the calling procedure as the result of “getf”.

The expression

    rf < 0 || rf >= NOFILE

is the logical disjunction (“or”) of the two simple relational expressions.

An example of a “goto” statement and associated label will be noted.

“fp” is assigned a value, which is an address, from the “rf”-th element of the array of integers “u_ofile”, which is embedded in the structure “u”.

The procedure “getf” returns a value to its calling procedure. This is either the vale of “fp” (i.e. an address) or “NULL”.