2

Is it safe to return a struct with array data member in C? Something like

struct my_str {
 int v[5];
};

struct my_str ret_stupid() {
 struct my_str rval;

 /*do something..*/

 return rval;
}

I don't know why... I'm a bit puzzled. (I've tried and it does work). Is there some standard explaining how this operation actually is performed? I mean the mechanism of struct return and assignment too could be useful to understand better.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
user8469759
  • 2,522
  • 6
  • 26
  • 50
  • `my_str` contains 5 `int`s, which are copied when you return the struct. – Colonel Thirty Two May 12 '15 at 15:36
  • Possible duplicate http://stackoverflow.com/questions/2702928/returning-a-struct-pointer – Javia1492 May 12 '15 at 15:36
  • @Javia1492 the question you linked is not a dup of this; what makes you believe it is? – mah May 12 '15 at 15:39
  • @Lukkio how it works is implementation-dependent, but what you should expect might be that the struct gets copied to the stack by the function returning it, and the caller takes its copy off the stack. If your caller did not have a valid prototype of the function returning a struct, you would expect corrupted results (but corrupted or not, it would be undefined behavior). – mah May 12 '15 at 15:48

4 Answers4

4

Is it safe to return a struct with array data member in C?

Yes.

struct are copied bit-wise. Bit-wise copying a struct that has an array as a member makes sure that the copy of struct has a copy of the array too.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

Structures are a lot like arrays. They can contain variables of any kind. Their addresses will be sorted stacked as long as you leave no gaps or invoke the preprocessor directive #pragma pack


"Is it safe", depends of the code hiding there..

/do something../

But in general - yes. This is just a function of type struct my_str and has to return struct my_str


What the structure contains - doesn't matter. Still safe to use.

Imobilis
  • 1,475
  • 8
  • 29
0

If it weren't for the array member, the return would be an "rvalue", a value that is just a copy of the value that you have inside the return expression. If you have

struct toto {
  double a;
};

struct toto g(void) {
   struct toto retval = { 0.0 };
   ...
   return retval;
}

int main(void) {
   printf("%g\n", g().a);
}

The argument of the printf call sees a copy of the variable retval that is used inside the function. g().a calls the function and uses the .a field of the return value.

This return value is and entity that is not an object but only lives because of its "value", called rvalue in the C jargon. It only can be found on the RHS of an assignment, thus the "r" in "rvalue".

The case that you are giving is actually specially treated, because a "value" is not sufficient for all use cases of the array. So this generates a so-called "object with temporary lifetime". This is needed because if you'd do ret_stupid().v[2] the [] operator wants to have a pointer, and a pointer can only point to an object, not a value.

These objects only "live" inside the expression that contains the function call, and even though they are not const qualified you are not allowed to modify them.

So all in all, this is a corner case of C, and you shouldn't abuse it.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • I don't understand the special treatment you're speaking about... could you be a bit more specific? – user8469759 May 12 '15 at 15:45
  • 1
    For the sake of clarity... i do not understand the write ret_stupid().v[2]... what does it mean? Moreover what's the difference between the struct return i proposed with a static array returned, which i know i CAN'T do it... – user8469759 May 12 '15 at 15:51
  • @Lukkio, please see my edit, I hope it is clearer, now. – Jens Gustedt May 12 '15 at 18:30
0

You can return a structure from a function without any problems. It's a well-defined part of the language. You can pass structures to functions as well - a structure is exactly the same as any built-in type for purposes of parameter passing, return values, and assignment.

Here's an example

#include <stdio.h>

int func(int x) 
{
 int r = x;
 return r;
}

int main(void)
{
 int x = 12;
 int y = func(x);
 printf("%d\n", y);
 return 0;
}
S.I.J
  • 979
  • 1
  • 10
  • 22