2

I am confused which style is better to write a function in C:

int function() 
{ 
     /*code block*/ 
    return result;
}

or

void function(int *result) 
{
    /*code block*/ 
}

Personally, I think the first one is clearer (and like Java-style), but when I saw some function in C is declared as the second style, likegets(), shmget(), and my teacher of Algorithm Course advises me to write the second-style declaration, like create_Queue(Queue *q), I am wondering if the second one is the C-style, which I should follow.

Abhinav Upadhyay
  • 2,477
  • 20
  • 32
Stephen.W
  • 1,649
  • 13
  • 14
  • Your question is too much opinion based for this site. Just note: there are other things to consider. If `queue_create` allocates an object, I personally think it is better to return the object (as shown, you cannot return an object with a pointer to object). Otherwise, there are other things to consider for a good design. If the return-value is more "natural", it should be prefered. It does not work for `fgets` (**never ever** use `gets`! If your teacher told you to use it, he should learn C, first) – too honest for this site Dec 06 '16 at 14:58
  • 3
    It depends entirely on the context. Neither is better than the other. – Jabberwocky Dec 06 '16 at 14:58
  • The first one can be used for direct assignation like `result=function();` and the other one will need to declare and define `result` before calling `function`. Don't compare Java and C, they come from two different worlds with different benefits and drawbacks. – A. Gille Dec 06 '16 at 14:59
  • Unless you need to do the second version (there may be no valid result, and you need to inform the caller via a return status), I think it's just complicating your code (as well as the call site) for no reason whatsoever. – StoryTeller - Unslander Monica Dec 06 '16 at 15:05
  • The first style is the only choice if the result of the function is to be used in an expression, like `sin(x)*pow(y, z)` – phuclv Dec 06 '16 at 15:22
  • @Olaf Agree this question is OT here. If you have an idea, what SE site, if any, would it be on topic? – chux - Reinstate Monica Dec 06 '16 at 18:10
  • @chux: I don't know the other sites well enough to dare recommend one. Actually this is a matter of experience and usage. Interface-design is one of the most important subjects for larger software projects. – too honest for this site Dec 06 '16 at 20:51
  • @Olaf According to [this](http://stackoverflow.com/help/dont-ask) I'd say this is still on-topic. None of the negative points apply, but many of the positive. If 'opinion-based' is applied too strictly, we'll ban many interesting and important questions. – alain Dec 06 '16 at 22:16
  • @alain: Indeed it was 50/50 between opiniated and too broad. There simply is no easy formula when to use what, but far too many aspects. And some are definitively personal preferences. Feel free to discuss with the other 4 CV'rs in SOCVR. – too honest for this site Dec 07 '16 at 00:08
  • @Olaf I would not object to closing it as a dupe (if there is a good target), I'm 40/60 about opinion-based, but I hardly see how this could be too broad. It's 1 o'clock here, maybe I'll come to the SOCVR tomorrow, but OTOH it's not really a problem for me if this stays closed, it's clear and OK that there are many different opinions about what should be closed and what shouldn't. – alain Dec 07 '16 at 00:24

3 Answers3

5

The first style is perfect for small types like int, double, etc.

The second makes sense for return values bigger than int, like structs.

This has the following advantages:

  • The result struct can live either on the stack or on the heap, at the caller's discretion.
  • There are no ownership problems, as it is clear that the caller is responsible for allocating and freeing the result struct.
  • The structure could even be longer than what is needed, or be embedded in a larger struct.
alain
  • 11,939
  • 2
  • 31
  • 51
3

This is mostly a style issue and therefore quite a bit subjective. You'd use either form on case-to-case basis.

However, the form void function (int *result) has the advantage that you could reserve the return value for an error code. It is custom practice to write libraries so that every function in the API returns the same kind of error type.

Reserving the return value for error codes also means that if the caller is not interested in the function result, they can ignore it by typing (void) function(x);.

Lundin
  • 195,001
  • 40
  • 254
  • 396
1

For simple cases such as a function which simply returns an int, first style is much clearer and straightforward.

The second style is preferred in certain cases, for example, if you want to get multiple values returned from the function. As per the C standard a function can return only one value, therefore to get a second value back, you can pass a pointer to the function, which the function can update. Following is a hypothetical example to illustrate this:

char *getline(FILE *f, int *size);

Consider a function getline which returns a string representing a line from the file, and since it is reading a line, you must want to know the length of the line as well, and to get that, you pass a pointer to an int to the function, which it will update after reading the line. This is good from performance point of view as well, because the function getline, in this case is doing the hardwork of scanning the characters from the file, so it might as well give us back the size of the line. Otherwise, after getting the string back, you would have to call strlen() yourself, which would repeat the same task. This small trick can help save many CPU instructions in performance critical code.

Abhinav Upadhyay
  • 2,477
  • 20
  • 32