API Design for C++

Category: Programming
Author: Martin Reddy
4.0
This Month Stack Overflow 1

Comments

by anonymous   2017-08-20

Opinions vary on whether output parameters should even be used, let alone how they should be documented. Still, they are in common use and your question is valid.

Whether a parameter should be marked as [in], [out], or [in,out] depends on the purpose of the parameter.

Usually, the purpose of an output parameter is to allow the called function to pass additional information to the calling function, when a single return value is inadequate. This "additional information" is passed via a reference parameter provided by the calling function. The reference parameter might be provided using the C++ reference operator (&), or by a pointer, which is a slightly different vehicle but which has the same result.

So if the purpose of the parameter is to allow the called function to provide information to the calling function, then it should be identified as an output in the documentation.

If a file handle or a filename is provided to a function through a parameter, that would be considered an input parameter, even though the function is intended to write to the file. This is because

  • the function is not passing information back to the calling routine via the parameter
  • writing to the file is considered a side-effect of the function.

If a reference parameter is used to pass information in both directions, then it should be documented as [in,out].

Furthermore

When documenting a function, think of the function as a service that is being provided to the caller(s). The audience for your documentation is the programmer writing the code that will call your function. Write the documentation as though you, the writer of the function, are unaware of the context or specifics of the calling code. The purpose of the documentation is to describe in general what the function does, and in detail how to use the function.

So if the designer of the function intends that dest be used as an output, it should be marked as an output. You should also consider the case when the caller is not interested in the data provided via that output. Usually this is indicated by the caller providing a null pointer as the argument to that parameter. Before writing any data to *dest, your function should test to make sure dest is not null. The documentation for parameter dest should state that if dest is a null pointer, then no data will be written.

Use const for Input Pointer Parameters

As an aside, if a pointer parameter is intended for input only, that parameter should be modified with the const keyword, as follows:

void Copy(int *dest, const int *src) { *dest = *src; }

This has the following benefits:

  • It will prevent the Copy function from writing to the *src location, if the programmer of the Copy function were to mistakenly attempt to do that
  • It informs and reassures the programmer writing the code that calls Copy that his src buffer is safe from being modified by Copy
  • It is self-documenting, if you are consistent in the use of const: pointer parameters that are marked const are obviously input-only, while pointer parameters that are not marked const are probably used for output.

See also