Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't C code return a struct?

Tags:

c

return

While it's very handy, I very rarely, if ever, come across functions that return structs (or unions) 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?

like image 802
user541686 Avatar asked Jan 04 '12 14:01

user541686


People also ask

Can we return a struct in C?

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.

Does returning a struct copy it?

Oh, yeah, one more missing piece: returning a struct from a function does a move and not a copy.

Should I return a struct or a pointer?

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.

Does struct exist in C?

In C programming, a struct (or structure) is a collection of variables (can be of different types) under a single name.


2 Answers

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.

like image 52
unwind Avatar answered Nov 15 '22 19:11

unwind


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.

like image 28
Dave Avatar answered Nov 15 '22 21:11

Dave