Returning a Struct from a Function

Discussion in 'C++' started by alex.j.k2@gmail.com, May 11, 2008.

  1. Guest

    Hello, newbie here.

    I'd like to know if there is a way to return a structure from a
    function, without creating any other intermediate variables. Also,
    this should be done such that the function can still be declared as
    inline.

    More precisely, given the structure:

    struct TwoFields {
    int Field_one;
    int Field_two;
    }

    I want a function like the following one, but without the
    extra declaration, "TwoFields myReturnStruct;":

    inline TwoFields ReturnMyFields(int myInt) {

    TwoFields myReturnStruct;

    myReturnStruct.Field_one = myInt/2;
    myReturnStruct.Field_two = myInt%2;

    return myReturnStruct;
    }

    The only reason I want this is speed efficiency, so if this is not
    worth doing please let me know.

    Alex
     
    , May 11, 2008
    #1
    1. Advertising

  2. john Guest

    dixit:
    > Hello, newbie here.
    >
    > I'd like to know if there is a way to return a structure from a
    > function, without creating any other intermediate variables. Also,
    > this should be done such that the function can still be declared as
    > inline.
    >


    The usual way is to pass a reference to the struct (as a parameter) in
    which you want to put the return value (the same for vector, list, ...)
     
    john, May 11, 2008
    #2
    1. Advertising

  3. Guest

    On May 11, 2:02 pm, john <> wrote:
    > dixit:
    >
    > > Hello, newbie here.

    >
    > > I'd like to know if there is a way to return a structure from a
    > > function, without creating any other intermediate variables. Also,
    > > this should be done such that the function can still be declared as
    > > inline.

    >
    > The usual way is to pass a reference to the struct (as a parameter) in
    > which you want to put the return value (the same for vector, list, ...)


    OK, that certainly works.

    But is this the only way to do it?

    What if I have a lot of code which returns a struct (or vector,
    etc..) by creating an intermediate variable in the function; and I do
    not want to modify all the occurrences of the function in the code,
    only the function itself.

    Can I eliminate the creation of the extra variable, while returning
    the struct (but not as a parameter) ?

    Also, thanks for the quick reply.

    Alex
     
    , May 11, 2008
    #3
  4. peter koch Guest

    On 11 Maj, 19:57, wrote:
    > Hello, newbie here.
    >
    >   I'd like to know if there is a way to return a structure from a
    > function, without creating any other intermediate variables. Also,
    > this should be done such that the function can still be declared as
    > inline.


    Yes. Any ordinary function will likely do so. The compiler is allowed
    to optimise this special case that has been given the name (N)RVO for
    (Named) Return Value Optimisation and all recent compilers should be
    able to use this strategy.
    >
    >   More precisely, given the structure:
    >
    > struct TwoFields {
    >    int Field_one;
    >    int Field_two;
    >
    > }
    >
    > I want a function like the following one, but without the
    > extra declaration, "TwoFields myReturnStruct;":
    >
    > inline TwoFields ReturnMyFields(int myInt) {
    >
    > TwoFields myReturnStruct;
    >
    > myReturnStruct.Field_one = myInt/2;
    > myReturnStruct.Field_two = myInt%2;
    >
    > return myReturnStruct;
    >
    > }
    >

    This looks fine to me.

    >   The only reason I want this is speed efficiency, so if this is not
    > worth doing please let me know.

    I can sympathise with your attitude - I used to think that way
    myself. But seriously: do you believe that the difference in execution
    time for that function is going to make any difference?

    /Peter
     
    peter koch, May 11, 2008
    #4
  5. Guest

    On May 11, 2:19 pm, peter koch <> wrote:
    > On 11 Maj, 19:57, wrote:
    >
    > > Hello, newbie here.

    >
    > > I'd like to know if there is a way to return a structure from a
    > > function, without creating any other intermediate variables. Also,
    > > this should be done such that the function can still be declared as
    > > inline.

    >
    > Yes. Any ordinary function will likely do so. The compiler is allowed
    > to optimise this special case that has been given the name (N)RVO for
    > (Named) Return Value Optimisation and all recent compilers should be
    > able to use this strategy.
    >
    >


    If I parse this correctly, you are saying that a good compiler will
    not actually make the extra allocation if it is not needed, even if I
    use the code in the initial post. Is that correct?


    > > The only reason I want this is speed efficiency, so if this is not
    > > worth doing please let me know.

    >
    > I can sympathise with your attitude - I used to think that way
    > myself. But seriously: do you believe that the difference in execution
    > time for that function is going to make any difference?
    >


    I genuinely do not know, but I thought it a good thing to know.
    I do use the function deep inside nested loops in a computation
    that takes days if not weeks, so I am trying to speed up genuine
    bottlenecks, not just doing it for the sake of frivolous efficiency.

    Thank you for the reply,
    Alex
     
    , May 11, 2008
    #5
  6. Guest

    On May 11, 2:45 pm, "Alf P. Steinbach" <> wrote:
    > * :
    >


    > > Can I eliminate the creation of the extra variable, while returning
    > > the struct (but not as a parameter) ?

    >
    > In general one should not optimize prematurely. However, designing a
    > program so that it needlessly copies megabytes of data in function
    > calls is ungood. The advice about optimization is really about
    > micro-optimization, not about not applying common sense.
    >


    Yes. In my defense, I did not do something as dumb as passing
    megabytes of data by value instead of reference. The values passed
    around are just one integer and a two integer struct, as in my
    example. Google led me to believe that there is not much speed
    difference in passing by reference instead of value for such small
    data -- sometimes (for some compilers) passing by value may be faster,
    Google said.

    > For a large vector or something like that, the simplest technique is
    > to provide 2 variants of your function:
    >
    > void getDataset( std::vector<Whatever>& result )
    > {
    > std::vector<Whatever> tempResult;
    > // Fill in tempResult here, then:
    > tempResult.swap( result );
    > }
    >
    > inline std::vector<Whatever> dataset()
    > {
    > std::vector<Whatever> result;
    > getDataset( result );
    > return result;
    > }
    >
    > Now users can just use the simple function call notation for
    > dataset(), until they discover that hey, this is a performance
    > bottleneck, at which time they measure, find that it's your dataset()
    > that's doing a lot of copying, and then switch to using getDataset().
    >


    That's a useful technique to know.

    > But that may in reality never occur, because a modern compiler is
    > likely to do Return Value Optimization, where a call of dataset()
    > produces machine code almost like it was getDataset that was called
    > directly -- the "almost" is because RVO is more efficient than that.
    >


    I just found out about (N)RVO today, in this thread. From a quick
    search it seems that my compiler (GNU GCC) does (N)RVO, so there was
    little reason for my initial worry.

    But, wow, did I get more than I bargained for bellow! : )

    > If one is pessimistic enough to believe that (1) the user's compiler
    > won't do RVO, and (2) the conditions for the performance problem
    > (enough data, called repeatedly) will be present, and (3) clean
    > notation like the dataset() function is required, then the only
    > recourse is to implement something like RVO manually. Usually that's
    > called "move semantics". For example, Andrei Alexandrescu has
    > implemented a std::vector replacement with move semantics (part of his
    > YASLI which it seems will never be completed), plus a general
    > framework for move semantics called Mojo. As another example, a
    > number of people were involved in implementing two smart pointers
    > called move_ptr for a Boost proposal; it was not accepted but still
    > the code could help. As a third example, Howard Hinnant has
    > implemented an emulation of C++0x unique_ptr (however, older compilers
    > such as MSVC 7.1 don't like that code).
    >
    > But if you don't want that new-fangled stuff, then there's nothing
    > very wrong in this context with just using std::auto_ptr, which is a
    > smart pointer with ownership transfer, almost like move semantics.
    > That usage can, if needed, be wrapped in a little class. The downside
    > is that using a smart pointer as result type is that (A) the notation
    > is a little bit less clean (after all, it's a pointer), and (B) it
    > involves an additional dynamic allocation and indirection.
    >


    Wow, thanks for that. It will take me a while to digest it.
    Fortunately, my problem is simple enough that I do not need to do RVO
    manually. But I might need it for other parts of my program, so I've
    saved your text for future reference.

    Thank you!

    Alex


    > Cheers, & hth.,
    >
    > - Alf
    >
    > --
    > A: Because it messes up the order in which people normally read text.
    > Q: Why is it such a bad thing?
    > A: Top-posting.
    > Q: What is the most annoying thing on usenet and in e-mail?
     
    , May 11, 2008
    #6
  7. wrote:
    > Hello, newbie here.
    >
    > I'd like to know if there is a way to return a structure from a
    > function, without creating any other intermediate variables. Also,
    > this should be done such that the function can still be declared as
    > inline.
    >
    > More precisely, given the structure:
    >
    > struct TwoFields {
    > int Field_one;
    > int Field_two;
    > }
    >
    > I want a function like the following one, but without the
    > extra declaration, "TwoFields myReturnStruct;":
    >
    > inline TwoFields ReturnMyFields(int myInt) {
    >
    > TwoFields myReturnStruct;
    >
    > myReturnStruct.Field_one = myInt/2;
    > myReturnStruct.Field_two = myInt%2;
    >
    > return myReturnStruct;
    > }
    >
    > The only reason I want this is speed efficiency, so if this is not
    > worth doing please let me know.


    Premture optimization alert !

    BTW - if you really want to do this - imho this is the easy way - and
    BTW - RVO will prolly happen.

    TwoFields & f = ReturnMyFields(v);

    Notice there is a temporary returned which is getting bound to a
    reference. In theory, this will only get constructed once - in the
    function ReturnMyFields; If your compiler is really smart, (and olot of
    them are) it will never hit memory and exist only in registers.

    Unless you "know" this is an issue for you, don't bother worrying about it.
     
    Gianni Mariani, May 11, 2008
    #7
  8. On 2008-05-12 00:33, Gianni Mariani wrote:
    > wrote:
    >> Hello, newbie here.
    >>
    >> I'd like to know if there is a way to return a structure from a
    >> function, without creating any other intermediate variables. Also,
    >> this should be done such that the function can still be declared as
    >> inline.
    >>
    >> More precisely, given the structure:
    >>
    >> struct TwoFields {
    >> int Field_one;
    >> int Field_two;
    >> }
    >>
    >> I want a function like the following one, but without the
    >> extra declaration, "TwoFields myReturnStruct;":
    >>
    >> inline TwoFields ReturnMyFields(int myInt) {
    >>
    >> TwoFields myReturnStruct;
    >>
    >> myReturnStruct.Field_one = myInt/2;
    >> myReturnStruct.Field_two = myInt%2;
    >>
    >> return myReturnStruct;
    >> }
    >>
    >> The only reason I want this is speed efficiency, so if this is not
    >> worth doing please let me know.

    >
    > Premture optimization alert !
    >
    > BTW - if you really want to do this - imho this is the easy way - and
    > BTW - RVO will prolly happen.
    >
    > TwoFields & f = ReturnMyFields(v);


    const TwoFields & f = ReturnMyFields(v);

    --
    Erik Wikström
     
    Erik Wikström, May 12, 2008
    #8
  9. Stefan Ram Guest

    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?= <> writes:
    >>>inline TwoFields ReturnMyFields(int myInt) {
    >>>TwoFields myReturnStruct; [...]
    >>>return myReturnStruct;

    >const TwoFields & f = ReturnMyFields(v);


    How long will the object created with »TwoFields myReturnStruct;« live?

    I used to believe that its lifetime would end not later than the
    evaluation of the full expression »ReturnMyFields(v)« or even
    when the control is leaving the block containing its declaration.
     
    Stefan Ram, May 12, 2008
    #9
  10. On 2008-05-12 18:42, Stefan Ram wrote:
    > =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?= <> writes:
    >>>>inline TwoFields ReturnMyFields(int myInt) {
    >>>>TwoFields myReturnStruct; [...]
    >>>>return myReturnStruct;

    >>const TwoFields & f = ReturnMyFields(v);

    >
    > How long will the object created with »TwoFields myReturnStruct;« live?
    >
    > I used to believe that its lifetime would end not later than the
    > evaluation of the full expression »ReturnMyFields(v)« or even
    > when the control is leaving the block containing its declaration.


    When you bind a temporary to a const reference the lifetime of the
    temporary is extended to last as long as the reference.

    --
    Erik Wikström
     
    Erik Wikström, May 12, 2008
    #10
  11. James Kanze Guest

    On May 12, 6:59 pm, Erik Wikström <> wrote:
    > On 2008-05-12 18:42, Stefan Ram wrote:


    > > =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?= <> writes:
    > >>>>inline TwoFields ReturnMyFields(int myInt) {
    > >>>>TwoFields myReturnStruct; [...]
    > >>>>return myReturnStruct;
    > >>const TwoFields & f = ReturnMyFields(v);


    > > How long will the object created with »TwoFields
    > > myReturnStruct;« live?


    > > I used to believe that its lifetime would end not later
    > > than the evaluation of the full expression
    > > »ReturnMyFields(v)« or even when the control is leaving
    > > the block containing its declaration.


    > When you bind a temporary to a const reference the lifetime of
    > the temporary is extended to last as long as the reference.


    That can easily be misunderstood (and often is). Formally, the
    rule is when the initialization expression of a reference is a
    temporary, the lifetime of the temporary is extended to
    correspond to the lifetime of that reference. Which isn't quite
    the same thing.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 13, 2008
    #11
  12. mojmir Guest

    On May 12, 6:59 pm, Erik Wikström <> wrote:

    > When you bind a temporary to a const reference the lifetime of the
    > temporary is extended to last as long as the reference.


    i'd just note that sun studio (at least v10) requires -
    features=tmplife
    option for this to work correctly, otherwise it will destroy the named
    temporary at the end of the expression by default.
    i spent few days on that one :)

    mojmir
     
    mojmir, May 14, 2008
    #12
  13. In message
    <>,
    mojmir <> writes
    >On May 12, 6:59 pm, Erik Wikström <> wrote:
    >
    >> When you bind a temporary to a const reference the lifetime of the
    >> temporary is extended to last as long as the reference.

    >
    >i'd just note that sun studio (at least v10) requires -
    >features=tmplife
    >option for this to work correctly, otherwise it will destroy the named
    >temporary


    What is a "named temporary"?

    >at the end of the expression by default.
    >i spent few days on that one :)
    >
    >mojmir


    --
    Richard Herring
     
    Richard Herring, May 20, 2008
    #13
    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. Chris Fogelklou
    Replies:
    36
    Views:
    1,405
    Chris Fogelklou
    Apr 20, 2004
  2. Ole
    Replies:
    4
    Views:
    606
    Michael Wojcik
    Oct 26, 2004
  3. Army1987
    Replies:
    19
    Views:
    494
    Richard Tobin
    May 19, 2007
  4. DiAvOl
    Replies:
    155
    Views:
    2,549
    Tim Rentsch
    Oct 11, 2008
  5. Shao Miller

    Function Returning Anonymous Struct

    Shao Miller, Aug 6, 2010, in forum: C Programming
    Replies:
    2
    Views:
    1,136
    Shao Miller
    Aug 7, 2010
Loading...

Share This Page