By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,018 Members | 878 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,018 IT Pros & Developers. It's quick & easy.

Best way to return newly created object

P: n/a
Hi all,

Sometimes I have a function which creates an object and returns it.
Some are sets, other vectors but that's not very important. In these
cases I do something like this:

vector<int> * f() {
vector<int> * v = new vector<int>;
return v;
}

Would there be any other way without pointers?

Would this work:
vector<int>& f() {
vector<int> v;
return v;
}

???

Cheers,

Paulo Matos

Jul 23 '05 #1
Share this Question
Share on Google+
29 Replies


P: n/a
Geo


pmatos wrote:
Hi all,

Sometimes I have a function which creates an object and returns it.
Some are sets, other vectors but that's not very important. In these
cases I do something like this:

vector<int> * f() {
vector<int> * v = new vector<int>;
return v;
}

Would there be any other way without pointers?

Would this work:
vector<int>& f() {
vector<int> v;
return v;
}

???

Cheers,

Paulo Matos


No, that won't work, 'v' will be destroyed when 'f' returns, you will
have an invalid reference. You should consider returning a
std::auto_ptr, or some other smart pointer.

Jul 23 '05 #2

P: n/a
pmatos wrote:
Hi all,

Sometimes I have a function which creates an object and returns it.
Some are sets, other vectors but that's not very important. In these
cases I do something like this:

vector<int> * f() {
vector<int> * v = new vector<int>;
return v;
}

Would there be any other way without pointers?

Would this work:
vector<int>& f() {
vector<int> v;
return v;
}


No. Never return a reference to a local object.

What you could do is turn it around. Let the function take the vector as
parameter and fill it:

void f(vector<int>& vec)
{
//fill vec
}

Jul 23 '05 #3

P: n/a
"pmatos" <po**@sat.inesc-id.pt> schrieb:
vector<int> * f() {
vector<int> * v = new vector<int>;
return v;
}


I suggest not to return a newly created object. Nobody knows what to
do with the pointer. How it is created? Do we have to delete it? Is it
a pointer on the heap or just an address of an existing object?

Indeed if the function and its caller don't use the same heap
management it could result in a serious problem. This is the case if
you create an object in a DLL and return a pointer up to an
application. If both modules are linked with a static runtime library
the application cannot delete the pointer.

I suggest to create the object outside the function. You can use the
function to fill it.

void f (vector<int>& v)
{
// fill v ...
}

T.M.
Jul 23 '05 #4

P: n/a

"pmatos" <po**@sat.inesc-id.pt> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Hi all,

Sometimes I have a function which creates an object and returns it.
Some are sets, other vectors but that's not very important. In these
cases I do something like this:

vector<int> * f() {
vector<int> * v = new vector<int>;
return v;
}

Would there be any other way without pointers?

Would this work:
vector<int>& f() {
vector<int> v;
return v;
}

???

Cheers,

Paulo Matos


vector<int> f()
{
return vector<int>;
}

regards,
ben
Jul 23 '05 #5

P: n/a
pmatos wrote:
Sometimes I have a function which creates an object and returns it.
Some are sets, other vectors but that's not very important. In these
cases I do something like this:

vector<int> * f() {
vector<int> * v = new vector<int>;
return v;
}
Thats usually a wrong way, because calling functions (which means the
programmer of the calling function) usually don't care about data not
created by themself.
Would this work:
vector<int>& f() {
vector<int> v;
return v;
}


Returning a ref to a local object is always wrong. Thinking about your
problem, the question arises:

In the calling function, you can either write:

vector<int> v;
or
vector<int> v = f();

I can't imagine a situation where someone would prefer the second solution.
So I assume you're trying to solve another problem. But without knowing
about it, nobody will be able to help you.

Mathias
Jul 23 '05 #6

P: n/a
"benben" <be******@hotmail.com> schrieb:
vector<int> f()
{
return vector<int>;
}


This will create a copy of the entire vector while the temporary
object will soon be forgotten unless the compiler supports a return
value optimization.

T.M.
Jul 23 '05 #7

P: n/a
Torsten Mueller wrote:
"benben" <be******@hotmail.com> schrieb:
vector<int> f()
{
return vector<int>;
}


This will create a copy of the entire vector while the temporary
object will soon be forgotten unless the compiler supports a return
value optimization.


Even _with_ RVO

vector<int> x = f()

will copy the vector twice.

Jul 23 '05 #8

P: n/a
"Panjandrum" <pa********@spambob.com> schrieb:
vector<int> f()
{
return vector<int>;
}


This will create a copy of the entire vector while the temporary
object will soon be forgotten unless the compiler supports a
return value optimization.


Even _with_ RVO

vector<int> x = f()

will copy the vector twice.


I had this in another news group some days ago. Look at the following
program:

#include <iostream>
using namespace std;

struct X
{
X() { cout << "X"; }
X( const X& ) { cout << "C"; }
};

X f()
{
return X();
}

X g()
{
X x;
return x;
}

#define TEST( code ) \
cout << #code << "\t: "; code; cout << endl

int main()
{
TEST( X x1( f() ); );
TEST( X x2( g() ); );
TEST( X const& x3 = f(); );
TEST( X const& x4 = g(); );
}

This little program compiles indeed different with several compilers.
I used the one I had on my machine. Look at this:

------------------------------------------------------------------------
MSVC 6

X x1( f() ); : X
X x2( g() ); : XC
X const& x3 = f(); : X
X const& x4 = g(); : XC
------------------------------------------------------------------------
MSVC 7.1

X x1( f() ); : X
X x2( g() ); : XC
X const& x3 = f(); : X
X const& x4 = g(); : XC
------------------------------------------------------------------------
gcc 3.2.3 (mingw)

X x1( f() ); : X
X x2( g() ); : X
X const& x3 = f(); : X
X const& x4 = g(); : X
------------------------------------------------------------------------
aCC (HP ANSI C++ B3910B A.03.27, HPUX)

X x1( f() ); : XC
X x2( g() ); : XCC
X const& x3 = f(); : X
X const& x4 = g(); : XC
------------------------------------------------------------------------

gcc does never (!) copy. Also the Microsoft compilers do avoid the
copy during return. They copy just the local variable. aCC on HPUX
does indeed copy during return. Because of this differences I would
not use this method of returning an object.

T.M.
Jul 23 '05 #9

P: n/a
Geo wrote:
You should consider returning a
std::auto_ptr, or some other smart pointer.


I agree with this advice. I recommend using a reference counting pointer
such as boost::shared_ptr for this. This will take care of memory
management automatically.

Regards
-Laurens
Jul 23 '05 #10

P: n/a
Torsten Mueller wrote:
gcc does never (!) copy.
The almost empty functions you wrote get inlined. Of course, if an
object is returned it must be copied and then it must be assigned to or
copied into another object (unless you use the returned temporary).
There is no black magic in C++.
Also the Microsoft compilers do avoid the
copy during return.
They copy just the local variable. aCC on HPUX
does indeed copy during return. Because of this differences I would
not use this method of returning an object.


.... and especially not because of a misleading example.

Jul 23 '05 #11

P: n/a
Panjandrum wrote:
Torsten Mueller wrote:
gcc does never (!) copy.
The almost empty functions you wrote get inlined.


gcc doesn't inline any functions unless optimizations are switched on.
Of course, if an object is returned it must be copied
No, NRVO can optimize that copy away.
and then it must be assigned to or copied into another object (unless you
use the returned temporary).
And also that copy can be optimized away, and gcc can do that.
There is no black magic in C++.


It's not black magic. It's a well-known optimization technique. Instead of
allocating the memory for the object locally in the called function, the
caller provides the memory and passes its address to the called function,
which then constructs the object directly into that memory, and so the
caller can use it without the need to copy it.
Jul 23 '05 #12

P: n/a
Rolf Magnus wrote:
Panjandrum wrote:
gcc doesn't inline any functions unless optimizations are switched on.
Of course, if an object is returned it must be copied


No, NRVO can optimize that copy away.


No! C and C++ programs consist of a stack of function calls. An object
that is returned to the calling function is copied (even with RVO).
Sorry, I don't have the nerve to argue with you any longer.

Jul 23 '05 #13

P: n/a
Panjandrum wrote:
Rolf Magnus wrote:
Panjandrum wrote:
gcc doesn't inline any functions unless optimizations are switched on.
Of course, if an object is returned it must be copied


No, NRVO can optimize that copy away.


No! C and C++ programs consist of a stack of function calls. An object
that is returned to the calling function is copied (even with RVO).
Sorry, I don't have the nerve to argue with you any longer.


Sorry, you are talking crap. The GCC result shows that the
object is never copied. If you run the following code, you will
see that the object always has the same address (not surprising
given that it is never copied). The C++ standard says that the
object does not need to be copied. What more evidence do you need?

#include <iostream>
using namespace std;

struct X
{
X() { cout << "X"; }
X( const X& ) { cout << "C"; }
};

X g()
{
X x;
cout << "[" << &x << "]";
return x;
}

#define TEST( code ) \
cout << #code << "\t: "; code; cout << endl

int main()
{
TEST( X x2( g() ); cout << &x2; );
TEST( X const& x4 = g(); cout << &x4; );
}

Jul 23 '05 #14

P: n/a
Me
> > > vector<int> f()
{
return vector<int>();
}


This will create a copy of the entire vector while the temporary
object will soon be forgotten unless the compiler supports a return
value optimization.


Even _with_ RVO

vector<int> x = f();

will copy the vector twice.


Wrong. At most it will do 1 default construction, 1 copy, and 2
destructions. With RVO it will just do 1 default construction and 1
destruction.

12.2/1 "Temporaries of class type are created in various contexts: ...
returning an rvalue"
6.6.3/2 "A return statement can involve the construction and copy of a
temporary object (12.2)."
8.5/14 "In certain cases, an implementation is permitted to eliminate
the copying inherent in this direct-initialization by constructing the
intermediate result directly into the object being initialized; see
12.2, 12.8."
12.8/15 "Whenever a temporary class object is copied using a copy
constructor, and this object and the copy have the same cv-unqualified
type, an implementation is permitted to treat the original and the copy
as two different ways of referring to the same object and not perform a
copy at all, even if the class copy constructor or destructor have side
effects."

Then 12.8 goes on to allow NRVO which is even more general than the
above code.

Jul 23 '05 #15

P: n/a
pmatos wrote:
Sometimes I have a function which creates an object and returns it.
Some are sets, other vectors but that's not very important.
In these cases I do something like this:

vector<int>* f(void) {
vector<int>* p = new vector<int>;
return p;
}
This is a bad idea.
Would there be any other way without pointers?

Would this work:

vector<int>& f(void) {
vector<int>* p = new vector<int>;
return *p;
}
And so is this.

Simply return by *value*:
cat f.cc

#include <vector>

std::vector<int> f(void) {
std::vector<int> v;
// modify v
return v;
}

Any decent optimizing C++ compiler will invoke
the Named Return Value Optimization (NRVO) --
the compiler recognizes v as a synonym for the return value
so that *no* copy is required!
Jul 23 '05 #16

P: n/a
Laurens wrote:
Geo wrote:
You should consider returning a std::auto_ptr,
or some other smart pointer.
I agree with this advice.


It's bad advice.
I recommend using a reference counting pointer
such as boost::shared_ptr for this.
This will take care of memory management automatically.


Nonsense!
The obvious best solution is to return by *value*.

Reference counting is routinely abused by C++ programmers.
It should be reserved for very special cases.
Objects that contain a reference counter can never truly be constants.
They not *thread safe*
and must be protected by [expensive] mutual exclusion
if they are used in threaded applications.
Jul 23 '05 #17

P: n/a
Torsten Mueller wrote:
I suggest to create the object outside the function.
You can use the function to fill it.

void f(std::vector<int>& v) {
// fill v ...
}


This is a bad idea and it is unnecessary.

C++ programmers should avoid functions that modify their arguments
but, if you *must* modify an argument, you should, at least,
return a reference to the modified argument:

std::vector<int>& f(std::vector<int>& v) {
// fill v
return v;
}

But the obvious solution here is to return by *value*:

std::vector<int> f(const size_t n) {
std::vector<int> v(n);
// fill v
return v;
}

Return by value simplifies code

const
std::vector<int> v = f(10);

and allows the application programmers to define constants
instead of compelling them to define variables
and initialize them in a second step.
The Named Return Value Optimization (NRVO)
allows the compiler to initialize v *directly*
from the call to f(10) *without* making any copies!
Jul 23 '05 #18

P: n/a
It's not black magic. It's a well-known optimization technique. Instead of
allocating the memory for the object locally in the called function, the
caller provides the memory and passes its address to the called function,
which then constructs the object directly into that memory, and so the
caller can use it without the need to copy it.


I wasn't aware of this, and if it's true, I'd certainly like to know more
about it. It'd be a very convenient thing.

You mean this? This I do all the time:

vector<int> & foobar(vector<int> & x)
{
// do stuff to x
return x;
}

int main()
{
vector<int> x(10000000);
x=foobar(x); // of course, = not necessary.
return 0;
}

This is trivial.

Or you mean it's all done transparently to the caller?

vector<int> foobar()
{
vector<int> x(10000000);
// do stuff to x
return x;
}

int main()
{
vector<int> x;
x=foobar();
return 0;
}

This indeed looks like voodoo. The vector::operator=() allocates the
necessary memory, and it does work with vector (I checked), but it
certainly doesn't work with valarray. You mean the compiler does all the
magic behind the scenes: it notices main::x will be allocated memory, and
that foo::x will no longer be needed after it's returned and assigned to
x, so it might as well use the same memory? That's pretty cool if the
compiler is that smart.

Using g++ 4.0, with -g -Wall. What optimization flags should I use to
avoid the copying? And how about valarray?
Jul 23 '05 #19

P: n/a
pmatos:

consider passing a pointer to a structure which contains every data
type you are in need of, along with a flag in the structure which
indicates which data type has been filled and therefore how to
process...

John

"pmatos" <po**@sat.inesc-id.pt> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Hi all,

Sometimes I have a function which creates an object and returns it.
Some are sets, other vectors but that's not very important. In these
cases I do something like this:

vector<int> * f() {
vector<int> * v = new vector<int>;
return v;
}

Would there be any other way without pointers?

Would this work:
vector<int>& f() {
vector<int> v;
return v;
}

???

Cheers,

Paulo Matos

Jul 23 '05 #20

P: n/a
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> schrieb:
I suggest to create the object outside the function.
You can use the function to fill it.
void f(std::vector<int>& v) {
// fill v ...
}
This is a bad idea and it is unnecessary.


Of course not. It avoids copying safely on *every* compiler.
C++ programmers should avoid functions that modify their arguments
but, if you *must* modify an argument, you should, at least, return
a reference to the modified argument:

std::vector<int>& f(std::vector<int>& v) {
// fill v
return v;
}
Why that? How is the return value related to the modified argument?
And what if there are two?

The only problem I see is to show the caller what's changed and what
is not. And this is just a question of strictly use of "const",
references and pointers in parameters. I use consequently const
references for constant parameters. If it's not const the caller can
be *sure* the parameter will be changed. It's very simple. I don't
understand any confusion about this. Mostly people are just too lazy
to use "const".
But the obvious solution here is to return by *value*:


No, returning by value is not a good idea having large objects and
applications being compiled with different compilers on several
platforms. I have a program on three platforms at the moment. I have
visible speed differences just because of such compiler dependent
stuff.

T.M.
Jul 23 '05 #21

P: n/a
Help me understand...
//g++-4.0.
#include <iostream>
#include <cstdlib>
#include <valarray>

using namespace std;

valarray<int> foo(int n)
{
valarray<int> x(n);
cerr << __FUNCTION__ << ": " << __LINE__ << ": "
<< &x << "\t" << x.size() << endl;
return x;
}

int main()
{
valarray<int> x=foo(3000);
valarray<int> y;

y = foo(2000);

cerr << __FUNCTION__ << ": " << __LINE__ << ": "
<< &x << "\t" << x.size() << endl;

cerr << __FUNCTION__ << ": " << __LINE__ << ": "
<< &y << "\t" << y.size() << endl;

return 0;
}

Jul 23 '05 #22

P: n/a
Amadeus W. M. wrote:
This indeed looks like voodoo.


The C++ Standard allows to elide 1 copy by RVO. That's all.

Jul 23 '05 #23

P: n/a
Amadeus W. M. wrote:
Help me understand...
//g++-4.0.
#include <iostream>
#include <cstdlib>
#include <valarray>

using namespace std;

valarray<int> foo(int n)
{
valarray<int> x(n);
cerr << __FUNCTION__ << ": " << __LINE__ << ": "
<< &x << "\t" << x.size() << endl;
return x;
}

int main()
{
valarray<int> x=foo(3000);
This is copy construction.
valarray<int> y;

y = foo(2000);
This is copy assignment, which can not be optimized away.

cerr << __FUNCTION__ << ": " << __LINE__ << ": "
<< &x << "\t" << x.size() << endl;

cerr << __FUNCTION__ << ": " << __LINE__ << ": "
<< &y << "\t" << y.size() << endl;

return 0;
}


Jul 23 '05 #24

P: n/a
Amadeus W. M. wrote:
It's not black magic. It's a well-known optimization technique.
Instead of allocating the memory for the object locally in the called function,
the caller provides the memory and passes its address to the called function,
which then constructs the object directly into that memory
so the caller can use it without the need to copy it.
I wasn't aware of this and, if it's true,
I'd certainly like to know more about it.


I used Google

http://www.google.com/

to search for

+"C++" +"NRVO"

and I found lots of stuff.
It'd be a very convenient thing.

You mean this? This I do all the time:

std::vector<int>& foobar(std::vector<int> & x) {
// do stuff to x
return x;
}

int main(int argc, char* argv[]) {
vector<int> x(10000000);
// x=foobar(x); // of course, = not necessary. foobar(x); // It's wrong. return 0;
}

This is trivial.

Or you mean it's all done transparently to the caller?

vector<int> foobar(void) {
vector<int> x(10000000);
// do stuff to x
return x;
}

int main(int argc, char* argv[]) {
vector<int> x = foobar(); // Use the copy constructor and *not* the assignment operator.
// The optimizer can elide the copy constructor
// but *not* the assignment operator. return 0;
}

This indeed looks like voodoo.
The vector::operator=() allocates the necessary memory
and it does work with vector (I checked)
but it certainly doesn't work with valarray.
You mean the compiler does all the magic behind the scenes:
it notices main::x will be allocated memory
and that foo::x will no longer be needed
after it's returned and assigned to x
so it might as well use the same memory?
You are confused.
You must avoid the assignment operator
and use the copy constructor instead.
That's pretty cool if the compiler is that smart.
All quality C++ compilers are that smart.
If your compiler does not implement the NRVO,
you should be shopping for a new C++ compiler
that does implement the NRVO.
Using g++ 4.0 with -g -Wall,
g++ -Wall -ansi -pedantic

Don't use the -g option unless you need to use the debugger.
What optimization flags should I use to avoid the copying?
And how about valarray?


The GNU C++ compiler, g++,
implements the Named Return Value Optimization (NRVO) by default.
Jul 23 '05 #25

P: n/a
Torsten Mueller wrote:
E. Robert Tisdale schrieb:

I suggest to create the object outside the function.
You can use the function to fill it.

void f(std::vector<int>& v) {
// fill v ...
}
This is a bad idea and it is unnecessary.


Of course not. It avoids copying safely on *every* compiler.
C++ programmers should avoid functions that modify their arguments
but, if you *must* modify an argument, you should, at least, return
a reference to the modified argument:

std::vector<int>& f(std::vector<int>& v) {
// fill v
return v;
}


Why that? How is the return value related to the modified argument?
And what if there are two?


I have just told you that
functions should *not* modify their arguments.
That goes double for two arguments. :-)

There are some exceptions
where operations must be performed "in place" on a variable object
but there is seldom any excuse for returning void.
You should always return something -- an exception (error code)
or a reference to the the object that was modified if nothing else.
This is a long standing tradition in C and C++.
Consider, for example, strcpy(char*, const char*)
which returns a pointer to the destination string or
operator<<(std::ostream&, int) which returns a reference
to the output stream which it modifies.
The only problem [that] I see
is to show the caller what's changed and what is not.
And this is just a question of strictly use of "const",
references and pointers in parameters.
Consequently, I use const references for constant parameters.
If it's not const the caller can be *sure* the parameter will be changed.
It's very simple.
I don't understand any confusion about this.
Mostly people are just too lazy to use "const".
But the obvious solution here is to return by *value*:


No, returning by value is not a good idea
[if you have] large objects and applications
being compiled with different compilers on several platforms.
I have a program on three platforms at the moment.
I have visible speed differences
just because of such compiler dependent stuff.


Using a bad C++ compiler is *not* a good excuse
for writing bad C++ code.
If your C++ compiler does not implement
the Named Return Value Optimization (NRVO),
you should be shopping for a new C++ compiler
that *does* implement the NRVO.

The market place is highly competitive
and quality implementations are available almost everywhere.
Inferior implementations should be discarded not coddled.
Jul 23 '05 #26

P: n/a
> I used Google

http://www.google.com/

to search for

+"C++" +"NRVO"
Funny. Ponder about your recommendation for a minute: how could I have
used google on something whose existence was not known to me? I did after
I read about it in this thread, of course.
You are confused.
You must avoid the assignment operator
and use the copy constructor instead.
Is this a commandment coming from a rocket scientist? Your advice is good,
and I don't mean any disrespect, but it would be better received if you
didn't speak in such a dismissive tone. People need to understand why, not
to be ordered.

And as a matter of fact, I know the constructor should be used and not the
assignment. However, constructing objects only upon the point when they
are needed (and parameters known), as opposed to declaring/constructing
them at the beginning of the function, confuses gdb, more often than not.

Using g++ 4.0 with -g -Wall,


g++ -Wall -ansi -pedantic

Don't use the -g option unless you need to use the debugger.


But I do. Doesn't everyone?

The GNU C++ compiler, g++,
implements the Named Return Value Optimization (NRVO) by default.


I figured, thanks!

Now NRVO works with the copy constructor only, and not with assignment. I
see no mention in the original post saying that he was going to use it
with the copy constructor. You're recommending something less general than
the scope of the original question, without even a warning, other than
"it's bad".

I realize that I've completely undermined my chances of ever working at
NASA.
Jul 23 '05 #27

P: n/a
Amadeus W. M. wrote:
Using g++ 4.0 with -g -Wall,


g++ -Wall -ansi -pedantic

Don't use the -g option unless you need to use the debugger.


But I do. Doesn't everyone?


I never use the debugger on code that I wrote.
I sometimes find it useful for analyzing code that other people wrote.
The GNU C++ compiler, g++,
implements the Named Return Value Optimization (NRVO) by default.


I figured, thanks!

Now NRVO works with the copy constructor only, and not with assignment.
I see no mention in the original post
saying that he was going to use it with the copy constructor.
You're recommending something less general than the scope of the original question
without even a warning, other than "it's bad".


This:

int main(int argc, char* argv[]) {
vector<int> x;
x = foobar();
return 0;
}

is bad. This:

int main(int argc, char* argv[]) {
vector<int> x = foobar();
return 0;
}

is better. And this:

int main(int argc, char* argv[]) {
const
vector<int> x = foobar();
return 0;
}

is better yet if you don't need to modify x in your program.
In general, you should avoid unnecessary program state variables
because they make your program more difficult to analyze
(read, understand and maintain).
Jul 23 '05 #28

P: n/a
Geo
E. Robert Tisdale wrote:
Using a bad C++ compiler is *not* a good excuse
for writing bad C++ code.
If your C++ compiler does not implement
the Named Return Value Optimization (NRVO),
you should be shopping for a new C++ compiler
that *does* implement the NRVO.

The market place is highly competitive
and quality implementations are available almost everywhere.
Inferior implementations should be discarded not coddled.


I guess working at NASA is similar to not living in the real world, I
would bet that most of us just don't have that choice.

Jul 23 '05 #29

P: n/a
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> schrieb:
There are some exceptions where operations must be performed "in
place" on a variable object but there is seldom any excuse for
returning void.
What a beautiful dogma. Why that? It's just my decision to return
something or not.
You should always return something -- an exception (error code) or a
reference to the the object that was modified if nothing else. This
is a long standing tradition in C and C++.
Tradition is also to use int or char instead of bool.
Consider, for example, strcpy(char*, const char*) which returns a
pointer to the destination string or operator<<(std::ostream&, int)
which returns a reference to the output stream which it modifies.
These return values are for concatenation of multiple following
operations. They are useful.

I have a library of special string functions based on the STL string
class. These functions always return a string object. Nobody asks for
the time needed to create these temporary objects but everyone wonders
"It's not very fast, isn't it?". Nobody thinks about heap
fragmentation. Until now I eliminated more than two millions of
absolutely senseless string objects created in just one single minute
of runtime. Tell me, is this paradigma ("always return something")
useful in this case?

There is a lot of situations where indeed no result is to return,
where no result exists, where it needs just more time to create and to
evaluate the result than to return just nothing. Why the hell should a
sleep-function return something? And what?
Using a bad C++ compiler is *not* a good excuse for writing bad C++
code.
You can really be proud on you for knowing the bad and the good things
in the world. Have you ever been working on a system with a *given*
compiler, a compiler that cannot be changed for several reasons, a
compiler you just have to live with, and a manager who wants still a
good program?
If your C++ compiler does not implement the Named Return Value
Optimization (NRVO), you should be shopping for a new C++ compiler
that *does* implement the NRVO.


As long as I know how the compiler works and what I have to do to
write a quality program, a readable one, a fast one, a program that
runs on *any* compiler, I will do this. This is my profession. And my
profession is also to know these things rather than to assume every
compiler will surely do it right and fast.

I think it's not always a bad idea to change function parameters
especially if there are more than one. I use it seldom but sometimes
everything else would be just more complicated. I always mention it in
a comment. I name the function in that way

bool GetLoginValues (string& uid,string& pwd,string& host);

And I strictly use "const" for everything that *is* const. There's
nothing evil.

T.M.
Jul 23 '05 #30

This discussion thread is closed

Replies have been disabled for this discussion.