Returning structures from functions.

Discussion in 'C Programming' started by daniel, Sep 11, 2008.

  1. daniel

    daniel Guest

    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.
     
    daniel, Sep 11, 2008
    #1
    1. Advertising

  2. daniel <> 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.
     
    Chris McDonald, Sep 11, 2008
    #2
    1. Advertising

  3. daniel

    Richard Guest

    Richard Heathfield <> 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
     
    Richard, Sep 11, 2008
    #3
  4. daniel

    James Kuyper Guest

    Richard wrote:
    > Richard Heathfield <> 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.
     
    James Kuyper, Sep 11, 2008
    #4
  5. On 11 Sep, 10:20, Richard Heathfield <> 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
    Bad Things happened.


    --
    Nick Keighley
     
    Nick Keighley, Sep 12, 2008
    #5
  6. daniel

    Richard Guest

    Nick Keighley <> writes:

    > On 11 Sep, 10:20, Richard Heathfield <> 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
    > Bad Things happened.


    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.
     
    Richard, Sep 12, 2008
    #6
  7. daniel

    CBFalconer Guest

    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
    > Bad Things happened.


    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>
    Try the download section.
     
    CBFalconer, Sep 12, 2008
    #7
  8. daniel

    Richard Guest

    CBFalconer <> 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
    >> Bad Things happened.

    >
    > 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?
     
    Richard, Sep 12, 2008
    #8
  9. Richard<> writes:
    > Nick Keighley <> 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
    >> Bad Things happened.

    >
    > 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.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Sep 12, 2008
    #9
  10. daniel

    Richard Guest

    Keith Thompson <> writes:

    > Richard<> writes:
    >> Nick Keighley <> 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
    >>> Bad Things happened.

    >>
    >> 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.
     
    Richard, Sep 12, 2008
    #10
  11. Richard<> writes:
    [big snip]
    > What a stupid idea. Why would you want to do that? It totally defeats
    > the reason for passing a pointer.

    [...]

    Ask politely, and I might explain it to you.

    --
    Keith Thompson (The_Other_Keith) <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"
     
    Keith Thompson, Sep 12, 2008
    #11
  12. In article <>,
    Keith Thompson <> wrote:
    >Richard<> writes:
    >[big snip]
    >> What a stupid idea. Why would you want to do that? It totally defeats
    >> the reason for passing a pointer.

    >[...]
    >
    >Ask politely, and I might explain it to you.


    Please to be googling on: "rhetorical question"
     
    Kenny McCormack, Sep 12, 2008
    #12
  13. daniel

    Flash Gordon Guest

    Richard wrote, On 12/09/08 17:28:
    > Keith Thompson <> writes:
    >
    >> Richard<> writes:
    >>> Nick Keighley <> 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
    >>>> Bad Things happened.
    >>> 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.


    You asked for a reason, you got one. Another is that the function might
    call another function which somehow modifies the original structure
    (e.g. through a global pointer to one of its fields). There are
    limitless possibilities for this kind of thing.

    <snip>

    >>> 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.


    In my experience with embedded systems it is quite common for the
    compiler/linker to not do checks like this. The compiler generates code
    to modify the stack pointer (or ar7, or whatever) with no knowledge of
    the memory layout and the linker links with no knowledge of the stack
    pointer modifications. Often you get to write the startup code in
    assembler yourself if you want to, so unless the compiler/linker check
    your startup code they know even less about how much space might be
    available. On top of this, you might have a heap growing towards the
    stack limiting space even further!
    --
    Flash Gordon
     
    Flash Gordon, Sep 12, 2008
    #13
  14. On 12 Sep, 11:22, Richard<> wrote:
    > Nick Keighley<> writes:
    > > On 11 Sep, 10:20, Richard Heathfield <> wrote:
    > >> daniel said:


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


    <snip>

    > > >> 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
    > > Bad Things happened.

    >
    > A bug. It happens.


    yes. I was simply pointing out, to the OP, a possible problem
    with passing structs by value. They have to be copied (usually).


    > Is there anything stopping the compiler passing a
    > pointer in real life anyway?


    have you used an implementation that did this?


    > I am amazed that any system allowed this program to compile and link to
    > be honest.


    really? Why?


    > 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


    have you used an implementaion that does this by default?
    Or are the checks extra code written into your build system?

    This error is childish? Sometimes passing structs by
    value is quite sensible.


    --
    Nick Keighley
     
    Nick Keighley, Sep 15, 2008
    #14
  15. daniel

    Richard Guest

    Nick Keighley <> writes:

    > On 12 Sep, 11:22, Richard<> wrote:
    >> Nick Keighley<> writes:
    >> > On 11 Sep, 10:20, Richard Heathfield <> wrote:
    >> >> daniel said:

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

    >
    > <snip>
    >
    >> > >> 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
    >> > Bad Things happened.

    >>
    >> A bug. It happens.

    >
    > yes. I was simply pointing out, to the OP, a possible problem
    > with passing structs by value. They have to be copied (usually).


    Note your "usually": lets call it *A*

    >
    >
    >> Is there anything stopping the compiler passing a
    >> pointer in real life anyway?

    >
    > have you used an implementation that did this?


    It was a question.

    Now getting back to *A*, what did you mean if you were not clear on what
    I eluded to?

    I was merely pointing out that a clever compiler does not HAVE to pass
    the structure if the called function does not update the struct in any
    way.


    >
    >
    >> I am amazed that any system allowed this program to compile and link to
    >> be honest.

    >
    > really? Why?


    Why do you think? It causes a crash that was avoidable by the tool set
    looking at the numbers involved. Note I mentioned "system" in my
    words. Indicating the toolset and target hw.

    >
    >
    >> 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

    >
    > have you used an implementaion that does this by default?
    > Or are the checks extra code written into your build system?
    >
    > This error is childish? Sometimes passing structs by
    > value is quite sensible.


    Of course. No one said anything else. But not ones which exceed the
    target stack that could be caught at build time. But then we are getting
    into system specifics and Falconer will have a fit ....
     
    Richard, Sep 15, 2008
    #15
  16. On Thu, 11 Sep 2008 01:56:19 -0700 (PDT), daniel
    <> wrote:

    > 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.


    It returns the entire struct value, which is effectively a copy. (It
    might not be implemented exactly that way, but that's the abstract
    semantics, and thus what is implemented must 'appear' the same.)

    > I mean s.b will be '1' after foo call ?
    >

    s is a local variable and no longer exists after foo() returns.
    But the .b field of _the returned value_ is '1', yes.

    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, Sep 22, 2008
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kelvSYC

    Returning structures

    kelvSYC, Feb 5, 2004, in forum: C++
    Replies:
    11
    Views:
    662
    Anubis
    Feb 9, 2004
  2. Xiangliang Meng
    Replies:
    1
    Views:
    1,652
    Victor Bazarov
    Jun 21, 2004
  3. tweak
    Replies:
    14
    Views:
    2,814
    Eric Sosman
    Jun 11, 2004
  4. Replies:
    11
    Views:
    688
    Christos Georgiou
    May 2, 2006
  5. Alfonso Morra
    Replies:
    11
    Views:
    741
    Emmanuel Delahaye
    Sep 24, 2005
Loading...

Share This Page