Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Returning a Struct from a Function

Reply
Thread Tools

Returning a Struct from a Function

 
 
alex.j.k2@gmail.com
Guest
Posts: n/a
 
      05-11-2008
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
 
Reply With Quote
 
 
 
 
john
Guest
Posts: n/a
 
      05-11-2008
http://www.velocityreviews.com/forums/(E-Mail Removed) 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, ...)
 
Reply With Quote
 
 
 
 
alex.j.k2@gmail.com
Guest
Posts: n/a
 
      05-11-2008
On May 11, 2:02 pm, john <(E-Mail Removed)> wrote:
> (E-Mail Removed) 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


 
Reply With Quote
 
peter koch
Guest
Posts: n/a
 
      05-11-2008
On 11 Maj, 19:57, (E-Mail Removed) 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
 
Reply With Quote
 
alex.j.k2@gmail.com
Guest
Posts: n/a
 
      05-11-2008
On May 11, 2:19 pm, peter koch <(E-Mail Removed)> wrote:
> On 11 Maj, 19:57, (E-Mail Removed) 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

 
Reply With Quote
 
alex.j.k2@gmail.com
Guest
Posts: n/a
 
      05-11-2008
On May 11, 2:45 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * (E-Mail Removed):
>


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


 
Reply With Quote
 
Gianni Mariani
Guest
Posts: n/a
 
      05-11-2008
(E-Mail Removed) 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.
 
Reply With Quote
 
Erik Wikström
Guest
Posts: n/a
 
      05-12-2008
On 2008-05-12 00:33, Gianni Mariani wrote:
> (E-Mail Removed) 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
 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      05-12-2008
=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?= <(E-Mail Removed)> 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.

 
Reply With Quote
 
Erik Wikström
Guest
Posts: n/a
 
      05-12-2008
On 2008-05-12 18:42, Stefan Ram wrote:
> =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?= <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
Returning a struct from a function - strange behavior DiAvOl C Programming 155 10-11-2008 07:18 AM
portability problem with a function returning a struct Army1987 C Programming 19 05-19-2007 10:07 PM
Access from function in struct (pointer to function) to other items in the struct (advanced) Ole C Programming 4 10-26-2004 09:43 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments