Velocity Reviews > Returning structures from functions.

# Returning structures from functions.

daniel
Guest
Posts: n/a

 09-11-2008
Hello ,

How safe is it to return a structure from a function.

Let's say we have the following situation:

typedef struct MyStruct{

int a;
char b;
} MyStruct;

MyStruct foo(void){
MyStruct s;

s.a = 2;
s.b = '1';
return s;
}

When function returns s , it must somehow make a "raw" copy of s? Is
this copy consistent.
I mean s.b will be '1' after foo call ?

Thanks,
Dan.

Chris McDonald
Guest
Posts: n/a

 09-11-2008
daniel <(E-Mail Removed)> writes:

>How safe is it to return a structure from a function.

>Let's say we have the following situation:

>typedef struct MyStruct{

> int a;
> char b;
>} MyStruct;

>MyStruct foo(void){
> MyStruct s;

> s.a = 2;
> s.b = '1';
> return s;
>}

>When function returns s , it must somehow make a "raw" copy of s? Is
>this copy consistent.
>I mean s.b will be '1' after foo call ?

What happens when you write a small range of programs, and test this.
Do you observe the behaviour that you expect, or something different?

--
Chris.

Richard
Guest
Posts: n/a

 09-11-2008
Richard Heathfield <(E-Mail Removed)> writes:

> daniel said:
>
>> Hello ,
>>
>>
>> How safe is it to return a structure from a function.

>
> Perfectly safe (all else being equal). See Section 6.2 of K&R2, first two
> sentences.
>
> The caveat is simply because it is possible for structures to contain
> unsafe data. Consider:
>
> struct foo { char *s; };
> struct foo bar(void)
> {
> char t[] = "Baz";
> struct foo quux;
> quux.s = t; /* Danger, Will Robinson! */
>
> return quux; /* Returning unusable pointer in quux - unsafe */
> }
>
> Yes, it's safe to return structs, in much the same way that it's safe to
> carry small cardboard boxes around. But they just *might* contain
> dynamite. (The trick is to be careful what you put in the box.)

Complete and utter scaremongering nonsense.

He could just as well have malloc'ed a struct and set the same field and
returned the pointer to a struct.

The standard data scoping applies regardless of whether a pointer to a
local or a pointer to a struct with a pointer to a local

James Kuyper
Guest
Posts: n/a

 09-11-2008
Richard wrote:
> Richard Heathfield <(E-Mail Removed)> writes:
>
>> daniel said:
>>
>>> Hello ,
>>>
>>>
>>> How safe is it to return a structure from a function.

>> Perfectly safe (all else being equal). See Section 6.2 of K&R2, first two
>> sentences.
>>
>> The caveat is simply because it is possible for structures to contain
>> unsafe data. Consider:
>>
>> struct foo { char *s; };
>> struct foo bar(void)
>> {
>> char t[] = "Baz";
>> struct foo quux;
>> quux.s = t; /* Danger, Will Robinson! */
>>
>> return quux; /* Returning unusable pointer in quux - unsafe */
>> }
>>
>> Yes, it's safe to return structs, in much the same way that it's safe to
>> carry small cardboard boxes around. But they just *might* contain
>> dynamite. (The trick is to be careful what you put in the box.)

>
> Complete and utter scaremongering nonsense.
>
> He could just as well have malloc'ed a struct and set the same field and
> returned the pointer to a struct.

Yes, it's also safe, in the analogous sense, to carry briefcases around,
but a briefcase might contain dynamite too. So?

How does saying "perfectly safe" constitute "scaremongering"? Where is
the "nonsense" in warning about the fact that while the return of the
value is safe, the value itself might be dangerous? The warning is
perfectly valid, and relevant. It's just a disguised version of the
problem in

char * bar(void)
{
char t[] = "Baz";
return t;
}

However, because it is a disguised version of that problem, it's a
harder one to spot.

Nick Keighley
Guest
Posts: n/a

 09-12-2008
On 11 Sep, 10:20, Richard Heathfield <(E-Mail Removed)> wrote:
> daniel said:

> > How safe is it to return a structure from a function.

>
> Perfectly safe (all else being equal). See Section 6.2 of K&R2, first two
> sentences.
>
> The caveat is simply because it is possible for structures to contain
> unsafe data. Consider:
>
> struct foo { char *s; };
> struct foo bar(void)
> {
> * char t[] = "Baz";
> * struct foo quux;
> * quux.s = t; /* Danger, Will Robinson! */
>
> * return quux; /* Returning unusable pointer in quux - unsafe */
>
> }
>
> Yes, it's safe to return structs,

and passing structs around by value can be expensive.
I once saw a function declared like this

void process_stats (struct Statistics);

when the programmer (probably) meant

void process_stats (struct Statistics*);

Since the stack was limited to 4K and struct Statistics was 11K

--
Nick Keighley

Richard
Guest
Posts: n/a

 09-12-2008
Nick Keighley <(E-Mail Removed)> writes:

> On 11 Sep, 10:20, Richard Heathfield <(E-Mail Removed)> wrote:
>> daniel said:

>
>> > How safe is it to return a structure from a function.

>>
>> Perfectly safe (all else being equal). See Section 6.2 of K&R2, first two
>> sentences.
>>
>> The caveat is simply because it is possible for structures to contain
>> unsafe data. Consider:
>>
>> struct foo { char *s; };
>> struct foo bar(void)
>> {
>> Â* char t[] = "Baz";
>> Â* struct foo quux;
>> Â* quux.s = t; /* Danger, Will Robinson! */
>>
>> Â* return quux; /* Returning unusable pointer in quux - unsafe */
>>
>> }
>>
>> Yes, it's safe to return structs,

>
> and passing structs around by value can be expensive.
> I once saw a function declared like this
>
> void process_stats (struct Statistics);
>
> when the programmer (probably) meant
>
> void process_stats (struct Statistics*);
>
> Since the stack was limited to 4K and struct Statistics was 11K

A bug. It happens. Is there anything stopping the compiler passing a
pointer in real life anyway?

I am amazed that any system allowed this program to compile and link to
be honest. It knows the size of the struct after all. One would have
thought there would be safety features in the build system to try and
avoid such childish errors.

CBFalconer
Guest
Posts: n/a

 09-12-2008
Nick Keighley wrote:
>

.... snip ...
>
> and passing structs around by value can be expensive.
> I once saw a function declared like this
>
> void process_stats (struct Statistics);
>
> when the programmer (probably) meant
>
> void process_stats (struct Statistics*);
>
> Since the stack was limited to 4K and struct Statistics was 11K

They would also have happened if declared as a local variable.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>

Richard
Guest
Posts: n/a

 09-12-2008
CBFalconer <(E-Mail Removed)> writes:

> Nick Keighley wrote:
>>

> ... snip ...
>>
>> and passing structs around by value can be expensive.
>> I once saw a function declared like this
>>
>> void process_stats (struct Statistics);
>>
>> when the programmer (probably) meant
>>
>> void process_stats (struct Statistics*);
>>
>> Since the stack was limited to 4K and struct Statistics was 11K

>
> They would also have happened if declared as a local variable.

You have repeated time and time again that stacks are "off
topic". Therefore it would be impossible for a "standards C programmer"
to consider such a beast when writing his code.

Which is it?

Keith Thompson
Guest
Posts: n/a

 09-12-2008
Richard<(E-Mail Removed)> writes:
> Nick Keighley <(E-Mail Removed)> writes:

[...]
>> and passing structs around by value can be expensive.
>> I once saw a function declared like this
>>
>> void process_stats (struct Statistics);
>>
>> when the programmer (probably) meant
>>
>> void process_stats (struct Statistics*);
>>
>> Since the stack was limited to 4K and struct Statistics was 11K

>
> A bug. It happens. Is there anything stopping the compiler passing a
> pointer in real life anyway?

Yes. If the function modifies its parameter, that change must not
affect the object that was passed as an argument.

The generated code *could* pass a pointer and then copy the structure
somewhere else, but on a system like the one described I can't think
of a good place to copy it.

> I am amazed that any system allowed this program to compile and link to
> be honest. It knows the size of the struct after all. One would have
> thought there would be safety features in the build system to try and
> avoid such childish errors.

You're assuming that the compiler is aware of the limited stack size
on the target system.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Richard
Guest
Posts: n/a

 09-12-2008
Keith Thompson <(E-Mail Removed)> writes:

> Richard<(E-Mail Removed)> writes:
>> Nick Keighley <(E-Mail Removed)> writes:

> [...]
>>> and passing structs around by value can be expensive.
>>> I once saw a function declared like this
>>>
>>> void process_stats (struct Statistics);
>>>
>>> when the programmer (probably) meant
>>>
>>> void process_stats (struct Statistics*);
>>>
>>> Since the stack was limited to 4K and struct Statistics was 11K

>>
>> A bug. It happens. Is there anything stopping the compiler passing a
>> pointer in real life anyway?

>
> Yes. If the function modifies its parameter, that change must not
> affect the object that was passed as an argument.

No. I said is there anything stopping the compiler passing an susing a
pointer. *Clearly* it can not do that if you pass the entire structure
and function modifies the contents for local usage. I didn't think I
would have to mention that.

> The generated code *could* pass a pointer and then copy the structure
> somewhere else, but on a system like the one described I can't think
> of a good place to copy it.

What a stupid idea. Why would you want to do that? It totally defeats
the reason for passing a pointer.

>
>> I am amazed that any system allowed this program to compile and link to
>> be honest. It knows the size of the struct after all. One would have
>> thought there would be safety features in the build system to try and
>> avoid such childish errors.

>
> You're assuming that the compiler is aware of the limited stack size
> on the target system.

Actually I was assuming there it didn't. Which is why I was amazed.