3

What is good programming style for writing C-language functions and function calls to functions which return pointers?

For example, if I have a function my_function which return two integers through pointer arguments. How should I call this function, such that it is easy for a person who is not familiar with my code, to see that it returns two values?

And how should I write the function definition?

For example, I could always put the return values last in the parameter list, and when I call the function, I could add some extra space to separate input arguments from return values.

Also, for the function definition, I could add an empty line with a comment between the input parameters and the return values. For example:

void my_function(
   int a,
   int b,
/* return values */
   int *c,
   int *d)
{
   /* do something */
}

int main()
{
   int a = 1;
   int b = 2;
   int c;
   int d;

   my_function(a,b,   &c, &d);
}
4

You could note the flow of information in the function definition:

void my_function(
   /*  in */ int  a,
   /*  in */ int  b,
   /* out */ int* c,
   /* out */ int* d)
{
   /* do something */
}

This way, it's easy to see what happens. If you export this function, you will also include the comments in the prototype so that everybody could see the direction of information flow.

Furthermore, adhere to one style in your functions. For example, if you write the return values always on the end of the parameter list and someone sees you calling

whatever(p1, p2, p3, &p4);

one will know that there's a high probability that p4 is the return value of your function.

  • Looks nice yes!.. what about calling the function? Is it ok to leave some space as I suggested in my question? – Håkon Hægland Mar 2 '15 at 10:07
  • @HåkonHægland: see edit: IMHO not needed. – eckes Mar 2 '15 at 10:09
3

I'd use a tool to document the code. E.g. with doxygen you can write:

/**
 *  \brief Performs something and stores result in \a c and \a d
 *
 *  \param[in]  a ...
 *  \param[in]  b ...
 *  \param[out] c ...
 *  \param[out] d ...
 *
 *  Detailed description here.
 */
void my_function(int a, int b, int *c, int *d)
{
   /* do something */
}

The special comment block has a simple structure (it's a C comment block with some additional markings). So it's easy to read and, at the same time, allows to extract documentation.

Ordering function parameters so that all input-only parameters are before any output parameters is quite common in C but it isn't the only option (e.g. memcpy).

Anyway the most important aspect is a uniform code style.

As a general rule I try to avoid OUT parameters whenever possible.

Also consider that:

  • in the C standard there are precedents for returning structures that contain all the results (the div / ldiv / C99 lldiv functions from <stdlib.h>);
  • mixing return value and return parameters is usually the least clean option (but having a function that return a status and return data via OUT parameters is sensible in C).

Somewhat related:

  • ... even better: write annotation comments on your parameters and generate the doxygen header from these annotations. This is what I'm doing. With Vim. – eckes Mar 2 '15 at 12:21
  • Thanks for the tips on using doxygen! I have not used that tool before.. But this inspired me to try it out.. – Håkon Hægland Mar 2 '15 at 12:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.