While it's very handy, I very rarely, if ever, come across functions that return struct
s (or union
s) in C, whether they are dynamically linked functions or statically defined functions.
They instead return the data through a pointer parameter.
(An dynamic example in Windows is GetSystemInfo
.)
What's the reason behind this?
Is it because of a performance issue, an ABI compatibility issue, or something else?
You can return a structure from a function (or use the = operator) without any problems. It's a well-defined part of the language. The only problem with struct b = a is that you didn't provide a complete type.
Oh, yeah, one more missing piece: returning a struct from a function does a move and not a copy.
There are two ways of "returning a structure." You can return a copy of the data, or you can return a reference (pointer) to it. It's generally preferred to return (and pass around in general) a pointer, for a couple of reasons. First, copying a structure takes a lot more CPU time than copying a pointer.
In C programming, a struct (or structure) is a collection of variables (can be of different types) under a single name.
I would say "performance", plus the fact that it's even possible sometimes seems to surprise C programmers. It's not ... in the general "flavor" of C, to many, to throw around large things such as structs as if they were mere values. Which, according to the language, they really are.
Along the same lines, many C programmers seem to automatically resort to memcpy()
when the need to copy structs arises, rather than just using assignment, too.
In C++ at least, there is something called "return value optimization" which is able to silently transform code like this:
struct Point { int x, y; };
struct Point point_new(int x, int y)
{
struct Point p;
p.x = x;
p.y = y;
return p;
}
into:
void point_new(struct Point *return_value, int x, int y)
{
struct Point p;
p.x = x;
p.y = y;
*return_value = p;
}
which does away with the (potentially stack-hungry) "true" return of a struct value. I guess even better would be this, not sure if they're that smart:
void point_new(struct Point *return_value, int x, int y)
{
return_value->x = x;
return_value->y = y;
}
I'm not sure if C compilers can do any of this, if they can't then I guess that might be a real argument against struct returns, for very performance-critical programs.
The reasons are mostly historical. In his paper, "The Text Editor sam
", Rob Pike writes
A related matter of programming style:
sam
frequently passes structures by value, which simplifies the code. Traditionally, C programs have passed structures by reference, but implicit allocation on the stack is easier to use. Structure passing is a relatively new feature of C (it is not in the standard reference manual for C14), and is poorly supported in most commercial C compilers. It’s convenient and expressive, though, and simplifies memory management by avoiding the allocator altogether and eliminating pointer aliases.
That being said, there are pitfalls to the technique; returning obscenely large structures chances stack overflow.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With