6.8. Functions

Each function body must have no more than 15 noncomment lines. [Long-function: 1-30 points]

A noncomment line is defined to be a line that has at least two noncomment, non-white-space characters. For example, a line that only contains a brace does not count as a noncomment line by this definition.

Do not violate other requirements in order to squash a long function definition down. Break the function up into smaller functions and document each function.


Do not change call-by-value parameters [Change CBV param: 1-5 points]

A function must not change the value of a parameter that is passed to it by value. See changing call-by-value parameters.

A function with a nonvoid return type must return a value. [No return: 1-5 points]

If a function whose return type is not void can reach its end without returning a result, you will get a warning (assuming you have requested warnings). Pay heed to those warnings.

Only one loop per function [Multiple loops: 2-8 points]

Each function body can only have one loop.

No duplicated function calls with same parameter [Dup call: 2-6 points]

A function body must not make two calls to the same nondestructive function with the same argument when avoiding that would be a simple matter of remembering the result. For example,
  for(i = 0; i < strlen(s); i++) 
  {
    ...
  }
recomputes strlen(s) each time around the loop. If s is not changed in the loop body, then that duplicate call can be avoided as follows.
  int slen = strlen(s);
  for(i = 0; i < slen; i++) 
  {
    ...
  }

Do not write a function call a second time as a way to get the result from a prior call. For example,

  process(x);
  if(process(x)) 
  {
    ...
  }
computes process(x) twice, ignoring the result the first time and testing the result the second time. If your intent is to compute process(x) once, write
  if(process(x)) 
  {
    ...
  }

This requirement does not mean that a program can never call the same function more than once with the same parameter. It only applies to the body of a single function, and only for cases where avoiding the duplicate function call is a simple matter of remembering its result or avoiding wasted calls.


No extraneous parameters [Extra-parameter: 1-3 points]

A function must not have extra parameters that either are unused or are unnecessary. A parameter is unnecessary if it provides information that the function could easily get from other parameters, or if the parameter is used solely as a local variable in the function, and neither passes information from the caller to the function nor passes information from the function to the caller.

Do not explicitly return a void value [Return void: 1 point]

If expression E has a void type, do not write
  return E;

No extraneous returns [Extra return: 1 point]

Do not write statement
  return;
where it is not justified. For example,
  void demo(int& x)
  {
    if(x > 0)
    {
       x = 2*x;
       return;
    }
    else
    {
       x = -x;
       return;
    }
  }
has extraneous returns. It is equivalent to
  void demo(int& x)
  {
    if(x > 0)
    {
       x = 2*x;
    }
    else
    {
       x = -x;
    }
  }

No crippled functions [Crippled function: 1-5 points]

A crippled function is one that unnecessarily fails to do its entire job, and relies on its caller either to get it started or to finish the job. Examples of things that a crippled function might do are
  • insist that its caller initialize an array for it;
  • insist that its caller perform a final step for it;
  • not work correctly on all sensible parameter values, and insist that its caller work around that.

Do not treat a function that is not crippled as if it is crippled. [Trust: 1-3 points]

If a function does a job, let it do its job. Do not try to work around a perceived mistake in the function that is not really there. For example,
  if(!isEmpty(x))
  {
    process(x);
  }
assumes that you either do not want to do process(x) if x is empty or that function process does not know that it should do nothing when x is empty. It that is a justified requirement of process (stated in the contract of process) then this is fine. But if process already does nothing on an empty value x, then just write
  process(x);

No strange compound jobs [Compound job: 1-2 pts]

Make each function have a sensible job. Do not make it do too much. For example, if your intent is to
  1. compute graph g;
  2. print a heading;
  3. print graph g
do not write one function that does the first two steps (compute graph g and print a heading). Those two jobs do not go together.

Do not unnecessarily tie jobs together [Tie together: 1-2 points]

This is really a continuation of the previous item. Where sensible, do not write a function that does two jobs so that, if you want to do one of the jobs, you are required to do both. For example, if you want to write the diameter of a graph, it makes sense to break the problem down into two steps: (1) compute the diameter of a graph; and (2) write the result. If you tie the two jobs together, so that the program cannot do one without doing the other, then the program is difficult to modify. Later, you might find that you want to compute the diameter of a graph without writing anything out. Remember that programs are frequently modified.

Do not use default parameters [Default parameter: 1-3 points]

We will not discuss default parameters in this course. Do not use them.