Passing structs to functions

P

Paul N

This is probably a basic question - I just have nagging doubts about
using temporaries.

Suppose I have a struct consisting of a number of values I want to
pass to a function together - for example, the size and position of a
window. If I do:

MyRect getsize() {
MyRect temp;
temp.x = 3; // etc
return temp; }

then this will, I think, return a temporary MyRect. As I see it, I can
use it either as:

void fun1(MyRect in); or void fun2(const MyRect& in);

and so can do

fun1(getsize()); or fun2(getsize());

Am I right in thinking that either of these will work, assuming the
functions only read the values in the MyRect? And that the second form
is preferred, as (potentially) requiring less copying?

And does it make a difference if the function is in fact a
constructor? For example:

Note::Note(const MyRect& in) : m_x(in.x) { }

n = new Note(getsize());

Thanks for any advice.
Paul.
 
V

Victor Bazarov

Paul said:
This is probably a basic question - I just have nagging doubts about
using temporaries.

Suppose I have a struct consisting of a number of values I want to
pass to a function together - for example, the size and position of a
window. If I do:

MyRect getsize() {
MyRect temp;
temp.x = 3; // etc
return temp; }

then this will, I think, return a temporary MyRect. As I see it, I can
use it either as:

void fun1(MyRect in); or void fun2(const MyRect& in);

The latter is a tad better (more efficient).
and so can do

fun1(getsize()); or fun2(getsize());
Yep.


Am I right in thinking that either of these will work, assuming the
functions only read the values in the MyRect? And that the second form
is preferred, as (potentially) requiring less copying?

Yep. Yep.
And does it make a difference if the function is in fact a
constructor? For example:

Note::Note(const MyRect& in) : m_x(in.x) { }

n = new Note(getsize());

Nope.

V
 
S

Sudarshan Narasimhan

Thanks. Looks like I might have finally got the hang of it.

Thanks. Looks like I might have finally got the hang of it.







Am I right in thinking that either of these will work, assuming the
functions only read the values in the MyRect? And that the second form
is preferred, as (potentially) requiring less copying?


I have a basic question about this point. When the function returns,
is there a copy involved?

MyRect getsize() {
MyRect temp;
temp.x = 3;
return temp; }


Now a temporary copy of 'temp' is created on the stack(and perhaps it
remains till it goes out of scope??) When i do this,

fun1(getsize()) - I dont see that the copy constructor is being called
(for the returned object) . So, is there a copy operation involved
here? In fact i see that the address of the object 'temp' is the same
in both getsize() and fun1()

So where is the copy here? And for sure, in fun2(), there is no copy
either as its pass by reference. Just wondering what difference is
there in pass by val and reference "FOR THIS PARTICULAR CASE". The
general case is of course that in reference, we dont copy the object
when passing it on to a func.
"And that the second form
is preferred, as (potentially) requiring less copying? "

In the example you have given, pass by value and reference seem to
make no difference as the function return val seems to be popped off
the stack and passed to the functions fun1() and fun2() without a copy
being involved. Am i correct about this???


Or more generally,

if i say,

MyRect mR = getsize(); // Should the copy constructor get called here?
It isnt getting called

const MyRect &mR = getsize() // Shouldnt get called here isnt it? Isnt
being called..

But if i do,

MyRect mR;

mR = getsize(); // Assignment operator is getting called


Can someone demistify how the compiler handles return by value from
functions and initializing variables from them?
 
B

Bo Persson

Sudarshan said:
Or more generally,

if i say,

MyRect mR = getsize(); // Should the copy constructor get called
here? It isnt getting called

It is optional. Most compilers will construct the result directly into
mR.
const MyRect &mR = getsize() // Shouldnt get called here isnt it?
Isnt being called..

But if i do,

MyRect mR;

mR = getsize(); // Assignment operator is getting called


Can someone demistify how the compiler handles return by value from
functions and initializing variables from them?

The compiler is allowed (but not required) to optimize the copy
constructor away.

We talk about Return Value Optimization (RVO) and Named Return Value
Optimizations (NRVO), where the compiler is allowed to skip the
copying, even when the copy constructor has visible side effects!



Here's an interesting article on how to get best performance by
passing by value. :)

http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/


Bo Persson
 
S

Sudarshan Narasimhan

It is optional. Most compilers will construct the result directly into
mR.








The compiler is allowed (but not required) to optimize the copy
constructor away.

We talk about Return Value Optimization (RVO) and Named Return Value
Optimizations (NRVO), where the compiler is allowed to skip the
copying, even when the copy constructor has visible side effects!

Here's an interesting article on how to get best performance by
passing by value.  :)

http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

Bo Persson


Thanks Bo, thats an intersting article.

But i was wondering why the compiler didnt use the same logic for
assignment and rather chose to run the assignment. Do language
standards set some rules for this or is it implementation dependent.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top