473,890 Members | 1,309 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Passing by const & and returning a temp vs passing by value and returningit

In the project I'm maintaining I've seen two distinct techniques used for
returning an object from a function. One is

AType function(AType const& arg)
{
AType retval(arg); // or default construction and then..
// some other processing and/or changing 'retval'
return retval;
}

void foo()
{
AType somevariable;

AType anothervariable = function(someva riable); // pass by ref
// some other processing
}

and the other is

AType function(AType retval)
{
// some other processing and changing 'retval'
return retval;
}

void foo()
{
AType somevariable;

AType anothervariable = function(someva riable); // pass by value
// some other processing
}

As you can see the difference is when the variable which later is returned
is constructed. Yes, I realize the difference is really minimal. It is
probably has no effect on performance (and I wouldn't try to speculate one
way or another). The number of objects [copy-] constructed is probably
the same (even in theory, RVO aside). The objects being passed around are
*not* polymorphic. What am I forgetting? Copy-construction is defined
for them and in general no tricks are played. All relatively straight-
forward.

Now, my question is, why would I want to prefer/preserve one way of using
values passed to the function or should I keep both? Do you see any reefs
under the surface, any potential issues with one method or with having
both methods in the same project? Would the optimizer stumble on one of
the methods and not the other, for example?

I'd appreciate any insight. Thanks!

V
Jul 23 '05 #1
25 2958
>> The number of objects [copy-] constructed is probably
the same (even in theory, RVO aside
No.
AType function(AType retval) --> copy constructor will be called .
Use this version only if AType has a simple and fast initialization
otherwise passing argument by reference is better ( const reference if you
will not modify the argument) .
Ahmed MOHAMED ALI

"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:nO******** ***********@new sread1.mlpsca01 .us.to.verio.ne t... In the project I'm maintaining I've seen two distinct techniques used for
returning an object from a function. One is

AType function(AType const& arg)
{
AType retval(arg); // or default construction and then..
// some other processing and/or changing 'retval'
return retval;
}

void foo()
{
AType somevariable;

AType anothervariable = function(someva riable); // pass by ref
// some other processing
}

and the other is

AType function(AType retval)
{
// some other processing and changing 'retval'
return retval;
}

void foo()
{
AType somevariable;

AType anothervariable = function(someva riable); // pass by value
// some other processing
}

As you can see the difference is when the variable which later is returned
is constructed. Yes, I realize the difference is really minimal. It is
probably has no effect on performance (and I wouldn't try to speculate one
way or another). The number of objects [copy-] constructed is probably
the same (even in theory, RVO aside). The objects being passed around are
*not* polymorphic. What am I forgetting? Copy-construction is defined
for them and in general no tricks are played. All relatively straight-
forward.

Now, my question is, why would I want to prefer/preserve one way of using
values passed to the function or should I keep both? Do you see any reefs
under the surface, any potential issues with one method or with having
both methods in the same project? Would the optimizer stumble on one of
the methods and not the other, for example?

I'd appreciate any insight. Thanks!

V

Jul 23 '05 #2

"Ahmed MOHAMED ALI" <ah*****@wanado o.fr> wrote in message
news:42******** *************** @news.wanadoo.f r...
The number of objects [copy-] constructed is probably
the same (even in theory, RVO aside No.
AType function(AType retval) --> copy constructor will be called .
Eh? Look at his post again:
AType function(AType const& arg)
{
AType retval(arg); // copy constructor called here
return retval;
}


The copy constructor is called there, too. The difference is that here it's
called inside the function, and in the other case it was called in order to
pass a copy to the function in the first place.
Use this version only if AType has a simple and fast initialization
otherwise passing argument by reference is better ( const reference if you
will not modify the argument) .
Ahmed MOHAMED ALI


I think you missed what I pointed out above, that both versions are making
copies. If he were writing functions that didn't return a copy (thus making
the copy neccessariy in both cases), then your advice would make more sense.
In this case, it's not apparent that there is a difference, which is why
Victor is looking for more insight (than he already has!) into the problem.

-Howard
Jul 23 '05 #3


Victor Bazarov wrote:

Now, my question is, why would I want to prefer/preserve one way of using
values passed to the function or should I keep both? Do you see any reefs
under the surface, any potential issues with one method or with having
both methods in the same project? Would the optimizer stumble on one of
the methods and not the other, for example?

I'd appreciate any insight. Thanks!

We (http://tinyurl.com/7y38k) prefer the form

void func(const myClass& input, myClass& output);

we discourage copy construction and assignment by default, our
make-a-new class script makes both of those methods private. Why? Well
our classes can contain 100Mb+ of data and we don't want those being
copied about or assigned unnecessarily, this we'll go to any lengths to
avoid someone inadvertantly writing:

myClass func(myClass input);
Jul 23 '05 #4

"Howard" <al*****@hotmai l.com> wrote in message
news:8bY%d.4368 15$w62.99167@bg tnsc05-
If he were writing functions that didn't return a copy (thus making the
copy neccessariy in both cases), then your advice would make more sense.


Re-worded to be more clear:

He's writing functions that return a copy, thus making the copy-construction
neccessary in both cases. If the functions were *not* returning a copy,
then your advice would make more sense.

-Howard

Jul 23 '05 #5

"lilburne" <li******@godzi lla.com> wrote in message
news:3a******** *****@individua l.net...


Victor Bazarov wrote:

Now, my question is, why would I want to prefer/preserve one way of using
values passed to the function or should I keep both? Do you see any
reefs
under the surface, any potential issues with one method or with having
both methods in the same project? Would the optimizer stumble on one of
the methods and not the other, for example?

I'd appreciate any insight. Thanks!
We (http://tinyurl.com/7y38k) prefer the form

void func(const myClass& input, myClass& output);


Yuk! :-)
we discourage copy construction and assignment by default, our make-a-new
class script makes both of those methods private. Why? Well our classes
can contain 100Mb+ of data and we don't want those being copied about or
assigned unnecessarily, this we'll go to any lengths to avoid someone
inadvertantly writing:

myClass func(myClass input);


Avoiding mistakes is a noble concept, but I think you go too far. I much
prefer that whenever I have only one output from a function, then that
output be the return value. I have at least a couple of reasons for that
preference. First, it makes it obvious what the output is, without having
to name it "output". Second, it allows use in an assignment or other
statement, instead of having to assign to a local variable and then write a
whole new statement to actually use it. (Think about operators... how would
you write operator +() given your method above?)

And since I prefer to only have one output from a function whenever
possible, I pretty much always follow that rule. (And of course, if I want
to actually modify the variable passed instead of returning something, then
I pass by reference or pointer, as appropriate.)

-Howard


Jul 23 '05 #6
Victor Bazarov wrote:
In the project I'm maintaining I've seen two distinct techniques used for
returning an object from a function. One is

AType function(AType const& arg) {
AType retval(arg); // or default construction and then..
// some other processing and/or changing 'retval'
return retval;
}

void foo(void) {
AType somevariable;

AType anothervariable = function(someva riable); // pass by ref
// some other processing
}

and the other is

AType function(AType retval) {
// some other processing and changing 'retval'
return retval;
}

void foo(void) {
AType somevariable;

AType anothervariable = function(someva riable); // pass by value
// some other processing
}

As you can see, the difference is when the variable which later is returned
is constructed. Yes, I realize the difference is really minimal. It is
probably has no effect on performance (and I wouldn't try to speculate one
way or another). The number of objects [copy-] constructed is probably
the same (even in theory, RVO aside). The objects being passed around are
*not* polymorphic. What am I forgetting? Copy-construction is defined
for them and in general no tricks are played. All relatively straight-
forward.

Now, my question is, why would I want to prefer/preserve one way of using
values passed to the function or should I keep both? Do you see any reefs
under the surface, any potential issues with one method or with having
both methods in the same project? Would the optimizer stumble on one of
the methods and not the other, for example?

I'd appreciate any insight.
A working example might help:
cat AType.h #ifndef GUARD_ATYPE_H
#define GUARD_ATYPE_H 1

#include <iostream>

class AType {
private:
// representation
int I;
public:
friend
std::ostream& operator<<(std: :ostream& os, AType const& t) {
return os << t.I;
}

AType(int i = 0): I(i) {
std::cerr << "AType(int) " << std::endl;
}

AType(AType const& t): I(t.I) {
std::cerr << "AType(ATyp e const&)" << std::endl;
}
};

#endif//GUARD_ATYPE_H

cat main.cc #include "AType.h"

#ifndef BY_VALUE
AType function(AType const& arg) { // pass by reference
AType retval(arg); // or default construction and then..
// some other processing and modifying 'retval'
return retval;
}
#else //BY_VALUE
AType function(AType retval) { // pass by value
// some other processing and modifying 'retval'
return retval;
}
#endif//BY_VALUE

int main(int argc, char* argv[]) {
const
AType somevariable(13 );
const
AType anothervariable = function(someva riable);
std::cerr << anothervariable << std::endl;
// some other processing
return 0;
}
g++ -Wall -ansi -pedantic -o main main.cc
./main AType(int)
AType(AType const&)
13 g++ -DBY_VALUE -Wall -ansi -pedantic -o main main.cc
./main

AType(int)
AType(AType const&)
AType(AType const&)
13

When you pass by value, the copy constructor is called *twice* --
once to copy the function argument and once again
to copy the [modified] function argument into the return value.
For this reason, pass by [const] reference is always preferred
over pass by value when passing large objects.
Jul 23 '05 #7
"Victor Bazarov" <v.********@com Acast.net> wrote in message
news:nO******** ***********@new sread1.mlpsca01 .us.to.verio.ne t...
In the project I'm maintaining I've seen two distinct techniques used for
returning an object from a function. One is

AType function(AType const& arg)
{
AType retval(arg); // or default construction and then..
// some other processing and/or changing 'retval'
return retval;
}

void foo()
{
AType somevariable;

AType anothervariable = function(someva riable); // pass by ref
// some other processing
}

and the other is

AType function(AType retval)
{
// some other processing and changing 'retval'
return retval;
}

void foo()
{
AType somevariable;

AType anothervariable = function(someva riable); // pass by value
// some other processing
}

As you can see the difference is when the variable which later is returned
is constructed. Yes, I realize the difference is really minimal. It is
probably has no effect on performance (and I wouldn't try to speculate one
way or another). The number of objects [copy-] constructed is probably
the same (even in theory, RVO aside). The objects being passed around are
*not* polymorphic. What am I forgetting? Copy-construction is defined
for them and in general no tricks are played. All relatively straight-
forward.

Now, my question is, why would I want to prefer/preserve one way of using
values passed to the function or should I keep both? Do you see any reefs
under the surface, any potential issues with one method or with having
both methods in the same project? Would the optimizer stumble on one of
the methods and not the other, for example?

I'd appreciate any insight. Thanks!

V


I would slightly prefer the const ref version. I find it a little clearer
and more logical. The reader might wonder, "Why is the client being asked to
pass in the return value?" It's also a little more flexible if you need to
refactor. Maybe at some point you will want to pass in a const BType & which
can be used to construct an AType but isn't an AType.

There are no big issues that I see though.

--
Cy
http://home.rochester.rr.com/cyhome/
Jul 23 '05 #8
E. Robert Tisdale wrote:
Victor Bazarov wrote:
In the project I'm maintaining I've seen two distinct techniques used for
returning an object from a function. One is
A working example might help:


No, it won't. See notes below.
[...]

When you pass by value, the copy constructor is called *twice* --
once to copy the function argument and once again
to copy the [modified] function argument into the return value.

For this reason, pass by [const] reference is always preferred
over pass by value when passing large objects.


When you pass by reference, the copy constructor is also called twice --
once to create a local variable from the reference passed as the argument
and once again to copy the modified function local object into the return
value. Your compiler apparently doing RVO behind your back. Try it with
a different compiler. On VC++ v7.1 you get two exact same outputs for two
different ways of passing the argument.

For this reason never trust the results any particular compiler gives you
when you need a conclusion about the behaviour in general.

V
Jul 23 '05 #9
Victor Bazarov wrote:
E. Robert Tisdale wrote:
Victor Bazarov wrote:
In the project I'm maintaining
I've seen two distinct techniques used for
returning an object from a function.
A working example might help:


No, it won't. See notes below.
[...]

When you pass by value, the copy constructor is called *twice* --
once to copy the function argument and once again
to copy the [modified] function argument into the return value.

> For this reason, pass by [const] reference is always preferred
> over pass by value when passing large objects.


When you pass by reference, the copy constructor is also called twice --
once to create a local variable from the reference passed as the argument
and once again to copy the modified function local object
into the return value.


This is a deficiency in your optimizing compiler.
Your compiler apparently doing RVO behind your back.
You probably mean
the *Named* Return Value Optimization (NRVO) in this case.
No it isn't doing the NRVO behind my back.
I expect any good optimizing C++ compiler
to perform this optimization for me.
Try it with a different compiler.
On VC++ v7.1 you get two exact same outputs
for two different ways of passing the argument.

For this reason never trust the results any particular compiler gives you
when you need a conclusion about the behaviour in general.


You are confused.
Your reasoning is flawed.

The problem with the pass by value version is that
*no* compiler will be able to optimize away the superfluous copy.
Even VC++ will eventually implement the NRVO
but the pass by value version -- function(AType) --
will *still* require two copies.

It is a bad idea to cobble your code
just to accommodate an inferior compiler.
If your C++ compiler does not implement the NRVO,
you should be shopping for a better optimizing C++ compiler.

The ANSI/IOS C++ standards don't specify
which optimizations are implemented.
They only specify which optimizations are allowed
and it is up to the marketplace
to weed out inferior implementations .
Jul 23 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
1414
by: J. Campbell | last post by:
Suppose I have an object that is concatinatable (sp) using the '+' operator (eg string). I have a function(func)that will do some work to the object and return an int. For several reasons it is desirable to have the ability to call the function like this: int myvalue = func(obj1 + obj2); because of this am I limited to passing by value? If I demand a pass by reference, must my calling procedure look like this, AnObj temp = obj1 +...
39
3112
by: JKop | last post by:
Back when I read my first C++ book, I was given the following scenario: class Cheese { public: int number_of_holes; int colour;
20
2162
by: christopher diggins | last post by:
I have heard it is considered good practice to pass function parameters as const& as often as possible, is this true? Is it possible to go overboard? And if so why? Thanks a lot in advance everyone! Christopher Diggins http://www.cdiggins.com
10
3182
by: Pete | last post by:
Can someone please help, I'm trying to pass an array to a function, do some operation on that array, then return it for further use. The errors I am getting for the following code are, differences in levels of indirection, so I feel it must have something to do with the way I am representing the array in the call and the return. Below I have commented the problem parts. Thanks in advance for any help offered. Pete
27
3869
by: Daniel Vallstrom | last post by:
I'm having problems with inconsistent floating point behavior resulting in e.g. assert( x > 0.0 && putchar('\n') && x == 0.0 ); holding. (Actually, my problem is the dual one where I get failed assertions for assertions that at first thought ought to hold, but that's not important.) At the end is a full program containing the above seemingly
7
2887
by: Andrej Prsa | last post by:
Hello, everyone! When a const int * argument is passed to a function, i.e. int f (const int *var) { printf ("%d\n", *var); } int main ()
6
1516
by: brian_harris | last post by:
I have a function that passes a string class pointer to a function, this function is then suppose to fill it and the outer function uses it. But I believe that I am running into problem due to manged memory. Because it has value in inner function, but does not have the assigned value in outher function. So I need to know how to declare this variable and make assignments correctly so that it will have value when it is back in outher...
19
2241
by: scroopy | last post by:
Is it impossible in C++ to create an assignment operator for classes with const data? I want to do something like this class MyClass { const int m_iValue; public: MyClass(int iVal):m_iValue(iVal){}
2
3446
by: ragged_hippy | last post by:
Hi, If I have a method that has string reference as a parameter, what happens if I pass a const char* variable to this method? One thought is that a temporary string will be created in the stack and the parameter will refer to this object. Is this correct? Does this mean if a constructor of a class has a string reference parameter, the temporary string that is created in the stack is
0
9822
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10819
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10923
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10462
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7169
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5851
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
6045
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
4271
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3277
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.