4

IMO all code that returns structure directly can be modified to return pointer to structure.

When is returning a structure directly a good practice?

new_perl
  • 7,345
  • 11
  • 42
  • 72
  • dupe? http://stackoverflow.com/questions/161788/are-there-any-downsides-to-passing-structs-by-value-in-c-rather-than-passing-a-p – goldPseudo Sep 26 '11 at 04:08

6 Answers6

7

Modified how? Returning a pointer to a static instance of the structure within the function, thus making the function non-reentrant; or by returning a pointer to a heap allocated structure that the caller has to make sure to free and do so appropiately? I would consider returning a structure being the good practice in the general case.

K-ballo
  • 80,396
  • 20
  • 159
  • 169
4

The biggest advantage to returning a complete structure instead of a pointer is that you don't have to mess with pointers. By avoiding the risks inherent with pointers, especially if you're allocating and freeing your own memory, both coding and debugging can be significantly simplified.

In many cases, the advantages of passing the structure directly outweigh the downsides (time/memory) of copying the entire structure to the stack. Unless you know that optimization is necessary, no reason not to take the easier path.

goldPseudo
  • 5,547
  • 1
  • 23
  • 38
2

I see the following cases as the ones I would most commonly opt for the passing structs directly approach:

  • "Functional programming" style code. Lots of stuff is passed around and having pointers would complicate the code a lot (and that is not even counting if you need to start using malloc+free)

  • Small structs, like for example

    struct Point{ int x, y; };
    

    aren't worth the trouble of passing stuff around by reference.


And lastly, lets not forget that pass-by-value and pass-by-reference are actually very different so some classes of programs will be more suited to one style and will end up looking ugly if the other style is used instead.

hugomg
  • 68,213
  • 24
  • 160
  • 246
  • 1
    What does "pass-by-reference" mean in C? – Chris Lutz Sep 26 '11 at 04:22
  • 2
    @Chris: It means passing anything that's a "reference" to a piece of data in the standard english sense of the word, e.g. a pointer, or an index into a global pool, or similar.. – R.. GitHub STOP HELPING ICE Sep 26 '11 at 06:02
  • @Chris Lutz: This term is not really C specific. When you pass a "normal" variable (say, an int) around, by setting another variable or passing it to a function, any changes to the second variable are *not* reflected in the original, since it actually was handling a copy. On the other hand if you pass a pointer (aka, a reference) around any changes are reflected back on the original variable as well. – hugomg Sep 26 '11 at 14:09
1

These other answers are good, but I think missingno comes closest to "answering the question" by mentioning small structs. To be more concrete, if the struct itself is only a few machine words long, then both the "space" objection and the "time" objection are overcome. If a pointer is one word, and the struct is two words, how much slower is the struct copy operation vs the pointer copy? On a cached architecture, I suspect the answer is "none aat all". And as for space, 2 words on stack < 1 word on stack + 2 words (+overhead) on heap.

But thes considerations are only appropriate for specific cases: THIS porion of THIS program on THIS architecture.

For the level of writing C programs, you should use whichever is easier to read.

luser droog
  • 18,988
  • 3
  • 53
  • 105
0

If you're trying to make your function side-effect free, returning a struct directly would help, because it would effectively be pass-by-value. Is it more efficient? No, passing by reference is quicker. But having no side effects can really simplify working with threads (a notoriously difficult task).

semisight
  • 914
  • 1
  • 8
  • 15
  • Hmm.. I would have said that passing structs around by value would have a negative effect om many multithreaded apps, (mod small structs, as already noted by other posters). A malloced pointer is easily, quickly and safely queued off to other threads. A struct returned to an auto variable has either to be maintained intact until the target thread has finished with it or the queue has to be as wide as the struct and so has to be locked for the whole time taken to copy the struct into the queue. – Martin James Sep 26 '11 at 10:26
0

There are a few cases where returning a structure by value is contra-indicated:

1) A library function that returns 'token' data that is to be re-used later in other calls, eg. a file or socket stream descriptor. Returning a complete structure would break encapsulation of the library.

2) Structs containing data buffers of variable length where the struct has been sized to accommodate the absolute maximum size of the data but where the average data size is much less, eg. a network buffer struct that has a 'dataLen' int and a 'char data[65536]' at its end.

3) Large structs of any typedef where the cost of copying the data becomes significant, eg:

a) When the struct has to be returned through several function calls - multiple copying of the same data.

b) Where the struct is subsequently queued off to other threads - wide queues means longer lock times during the copy-in/copy-out and so increased chance of contention. That, and the size of the struct is inflicted on both producer and consumer thread stacks.

c) Where the struct is often moved around between layers, eg. protocol stack.

4) Where structs of varying def. are to be stored in any array/list/queue/stack/whateverContainer.

I suspect that I am so corrupted by c++ and other OO languages that I tend to malloc/new almost anything that cannot be stored in a native type

Rgds, Martin

Martin James
  • 24,453
  • 3
  • 36
  • 60