473,385 Members | 1,311 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

pre return optimization

consider:

struct memory_pig{//a really large type:

memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};

memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};

~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};

//etc...

};///struct memory_pig

memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;
};

any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish

the last line of output may repeat based on how the result is
stored(rvo) or not.
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo' in PASCAL you can write:

function foo:memory_pig
begin
foo:=something;
{etc...}
foo:=somthing_else;
end

that is you can refrence the returned object inside the function and
decrease the overhead for copying large objects.C++ lacks such syntax
and IMHO we should be able to mark the result object as referencing
the actual return so that there is no need for the extra copy
construction;this is espesifically beneficall when dealing with
operator definitions .We can declare the return itself as an object.I
suggest the following syntax:

class ret_type funxn (paramlist){
ret_type return /*optional:*/(initiallizer params);

//etc...

if(false)return;//return like void functions

//return something;//error:named return accepts no param.

return=something;//ok;
return=something_else;
return.member_funxn();
another_funcxn(return);

};

Provided that 'return' is declared as an object { whenever you use the
'return' keyword inside pharantesis or accompanied via an operator ?
the return object is referenced :otherwise a parameterless 'return'
returns to the caller.
The return object is an lvalue inside the function and can be aliased
for readability:

memory_pig foo(){
memory_pig return , & result=return;
result=something;
//etc...
result=something_else;
};

and whenever 'foo' is called the output looks like this:

mem pig default

the unnessesary copy/move has vanished and the destruction of
temporary depends on what you do with it.

regards,
FM.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 9 '07 #1
18 2072
On 2007-10-09 17:56, terminator(jam) wrote:
consider:

struct memory_pig{//a really large type:

memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};

memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};

~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};

//etc...

};///struct memory_pig

memory_pig foo(){
memory_pig result;
result=something;
This should be

memory_pig result = something;

or

memory_pig result(something);

//etc...
result=something_else;
return result;
};

any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish

the last line of output may repeat based on how the result is
stored(rvo) or not.

With some smart coding you can transform the above to:

memory_pig foo(){
// ...
return memory_pig(something, something_else);
}

And with RVO you should only have one constructor call.
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo' in PASCAL you can write:

function foo:memory_pig
begin
foo:=something;
{etc...}
foo:=somthing_else;
end

that is you can refrence the returned object inside the function and
decrease the overhead for copying large objects.
I am not familiar with what that exactly means in Pascal, is it
something similar to

void foo(memory_pig& ret) {
// ...
ret = something;
// ...
ret = something_else;
}

Another thing that you seem to forget is that for large objects the
assignment is not cheap either, sometimes even more costly than a
constructor call.

--
Erik Wikström
Oct 9 '07 #2
terminator(jam) wrote:
consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish
I'm not sure I understand. Even in a worst case scenario, I
can't see where there would be more than two copies of
memory_pig in memory at a given time. Given the explicit
authorization of NRVO by the standard, I would expect that
in most implementations, there is never more than one.
the last line of output may repeat based on how the result
is stored(rvo) or not. So,two objects of a large type
will be constructed and at least one is destructed on
every call to 'foo' in PASCAL you can write:
function foo:memory_pig
begin
foo:=something;
{etc...}
foo:=somthing_else;
end
Not can, in Pascal, you have to write it that way.

It basically comes out to the same thing: the Pascal
compiler generates a local variable with the name of foo for
the return; if the name foo is used on the left hand side of
an assignment, it refers to the local variable, and if it is
used on the right hand side, it refers to the function.

And of course, in C++, unlike in Pascal, you can return an
expression directly, without first assigning it to a local
variable.
that is you can refrence the returned object inside the
function and decrease the overhead for copying large
objects. C++ lacks such syntax and IMHO we should be able
to mark the result object as referencing the actual return
so that there is no need for the extra copy construction;
this is espesifically beneficall when dealing with
operator definitions.
The current C++ standard leaves this up to the
implementation, but explicitly allows it. The situation in
C++ is more complicated than in Pascal, however, since you
can return from anywhere, e.g.:

memory_pig
foo()
{
memory_pig result ;
// ...
if ( someCondition ) {
memory_pig aDifferentResult ;
// ...
return aDifferentResult ;
}
// ...
return result ;
}

Whether this is a feature or a defect could be debated, but
it certainly cannot be removed from the language without
breaking a considerable amount of existing code.

--
James Kanze (GABI Software) mailto:ja*********@gmail.com
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

Oct 10 '07 #3
On Oct 10, 11:18 am, James Kanze <james.ka...@gmail.comwrote:
terminator(jam) wrote:
consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish

I'm not sure I understand. Even in a worst case scenario, I
can't see where there would be more than two copies of
memory_pig in memory at a given time. Given the explicit
authorization of NRVO by the standard, I would expect that
in most implementations, there is never more than one.
the last line of output may repeat based on how the result
is stored(rvo) or not. So,two objects of a large type
will be constructed and at least one is destructed on
every call to 'foo' in PASCAL you can write:
function foo:memory_pig
begin
foo:=something;
{etc...}
foo:=somthing_else;
end

Not can, in Pascal, you have to write it that way.

It basically comes out to the same thing: the Pascal
compiler generates a local variable with the name of foo for
the return; if the name foo is used on the left hand side of
an assignment, it refers to the local variable, and if it is
used on the right hand side, it refers to the function.
C++ generates an unnamed local variable which is not destructed by the
function ,this variable is constructed right before destruction of
other automatic variable which means it does not overwrite any
existing automatic variable ,So it has to be allocated in a separate
portion of [stack]memory.I just think it is posible to guess where the
'return' value is to be placed right at the beginning of the
function,so it can be constructed and refrenced before returning.
the choice between two modes of returning(name vs traditional) is left
to the programmer.
>
And of course, in C++, unlike in Pascal, you can return an
expression directly, without first assigning it to a local
variable.
that is you can refrence the returned object inside the
function and decrease the overhead for copying large
objects. C++ lacks such syntax and IMHO we should be able
to mark the result object as referencing the actual return
so that there is no need for the extra copy construction;
this is espesifically beneficall when dealing with
operator definitions.

The current C++ standard leaves this up to the
implementation, but explicitly allows it. The situation in
C++ is more complicated than in Pascal, however, since you
can return from anywhere, e.g.:

memory_pig
foo()
{
memory_pig result ;
// ...
if ( someCondition ) {
memory_pig aDifferentResult ;
// ...
return aDifferentResult ;
}
// ...
return result ;
}

Whether this is a feature or a defect could be debated, but
it certainly cannot be removed from the language without
breaking a considerable amount of existing code.
I believe it is a feature for many cases and a defect in many other
cases (operator functions)and I do not mean to remove anything from
the existing language.I just want to make it possible avoid the second
construction that happens at the end of a function (either move or
copy).

regards,
FM.

Oct 11 '07 #4
On Oct 9, 7:08 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-10-09 17:56, terminator(jam) wrote:


consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;

This should be

memory_pig result = something;

or

memory_pig result(something);
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish
the last line of output may repeat based on how the result is
stored(rvo) or not.

With some smart coding you can transform the above to:

memory_pig foo(){
// ...
return memory_pig(something, something_else);

}

And with RVO you should only have one constructor call.
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo' in PASCAL you can write:
function foo:memory_pig
begin
foo:=something;
{etc...}
foo:=somthing_else;
end
that is you can refrence the returned object inside the function and
decrease the overhead for copying large objects.

I am not familiar with what that exactly means in Pascal, is it
something similar to

void foo(memory_pig& ret) {
// ...
ret = something;
// ...
ret = something_else;

}
yes,but just fancy yourself definning an operator instead of a normal
function.If operators could be declared as objects rather than
functions ,one could declare them as instances of functor classes and
solve the problem.BTW it looks very hard to parse since this would
need major changes in semantics;I think working on the return will be
easier.
Another thing that you seem to forget is that for large objects the
assignment is not cheap either, sometimes even more costly than a
constructor call.
that was just an illustration replace it with compound
assignment(+= , ...) or any other sort of referencing( member/static
function,...) . I just want to return the object which is processed in
the function,not a copy/moved object .

regards,
FM.

Oct 11 '07 #5
On 2007-10-11 09:56, terminator wrote:
On Oct 9, 7:08 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2007-10-09 17:56, terminator(jam) wrote:
consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;

This should be

memory_pig result = something;

or

memory_pig result(something);
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo' in PASCAL you can write:
function foo:memory_pig
begin
foo:=something;
{etc...}
foo:=somthing_else;
end
that is you can refrence the returned object inside the function and
decrease the overhead for copying large objects.

I am not familiar with what that exactly means in Pascal, is it
something similar to

void foo(memory_pig& ret) {
// ...
ret = something;
// ...
ret = something_else;

}

yes,but just fancy yourself definning an operator instead of a normal
function.If operators could be declared as objects rather than
functions ,one could declare them as instances of functor classes and
solve the problem.
In C++ operators and functions are the same thing, operators just have a
fancier syntax. I still do not see the problem, please explain in more
detail.
BTW it looks very hard to parse since this would
need major changes in semantics;I think working on the return will be
easier.
I do not know how hard the above is to parse but all C++ compilers that
I know of can do it, it is very standard C++.

--
Erik Wikström
Oct 11 '07 #6
On 2007-10-12 15:58, terminator wrote:
On Oct 11, 12:01 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2007-10-11 09:56, terminator wrote:


On Oct 9, 7:08 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-10-09 17:56, terminator(jam) wrote:
consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;
>This should be
> memory_pig result = something;
>or
> memory_pig result(something);
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo' in PASCAL you can write:
function foo:memory_pig
begin
foo:=something;
{etc...}
foo:=somthing_else;
end
that is you can refrence the returned object inside the function and
decrease the overhead for copying large objects.
>I am not familiar with what that exactly means in Pascal, is it
something similar to
>void foo(memory_pig& ret) {
// ...
ret = something;
// ...
ret = something_else;
>}
yes,but just fancy yourself definning an operator instead of a normal
function.If operators could be declared as objects rather than
functions ,one could declare them as instances of functor classes and
solve the problem.

In C++ operators and functions are the same thing, operators just have a
fancier syntax. I still do not see the problem, please explain in more
detail.

**I certainly do disaggree.** operators follow a dedicated syntax ,you
cannot change a binary operator to a void return ternary one:
What I meant was that overloaded operators are just special functions.
While they do have special syntax, special precedence rules, and only a
few allowed forms, when it comes to the generated code it is just like
any other function call. Thus they are only functions with fancier syntax.
BTW it looks very hard to parse since this would
need major changes in semantics;I think working on the return will be
easier.

I do not know how hard the above is to parse but all C++ compilers that
I know of can do it, it is very standard C++.

I wrote:
>If operators could be declared as objects rather than
functions ,one could declare them as instances of functor classes and
solve the problem.BTW it looks very hard to parse since this would
need major changes in semantics;I think working on the return will be
easier.

that meant to treat operators as objects(not functions),which was a
stupid idea.
If you look at your post that I replied to it looked like you were
referring to the piece of code that I wrote, which is why I replied as I
did.

--
Erik Wikström
Oct 12 '07 #7
On Oct 9, 8:56 am, "terminator(jam)" <farid.mehr...@gmail.comwrote:
consider:

struct memory_pig{//a really large type:

memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};

memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};

~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};

//etc...

};///struct memory_pig

memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;

};

any time 'foo' is called the output will contain the following
sequence:

mem pig default
mem pig copy
mem pig finish

the last line of output may repeat based on how the result is
stored(rvo) or not.
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo'
The C++ Standard already allows the "(Named) Return Value
Optimization" (NRVO or RVO for short). The optimization allows (under
certain conditions) the compiler to construct the result of a function
call "in place" - that is, directly in the object initialized with the
function call result.

So, to take advantage of this optimization, a program should use the
result of a function call to initialize an object, instead of
assigning the function result to an existing object.

For example:

#include <iostream>

using std::cout;

struct memory_pig
{ // a really large type:
memory_pig()
{
cout << "mem pig default\n";
}
memory_pig(memory_pig const&)
{
cout << "mem pig copy\n";
}
~memory_pig()
{
cout << "mem pig finish\n";
}
};

memory_pig foo()
{
memory_pig result;
// ...
return result;
}

int main()
{
memory_pig m1 = foo();
memory_pig m2 = foo();
memory_pig m3 = foo();
}

I compiled the above program twice, once with and once without NRVO.
The output of both programs is shown in the two columns below. As this
comparison shows, NRVO can be a particular effective optimization -
even for a small C++ program like the one used in this example.

Program Output

Without NRVO: With NRVO:

mem pig default mem pig default
mem pig copy mem pig default
mem pig finish mem pig default
mem pig copy mem pig finish
mem pig finish mem pig finish
mem pig default mem pig finish
mem pig copy
mem pig finish
mem pig copy
mem pig finish
mem pig default
mem pig copy
mem pig finish
mem pig copy
mem pig finish
mem pig finish
mem pig finish
mem pig finish

Greg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 14 '07 #8
On Oct 14, 11:08 am, Greg Herlihy <gre...@pacbell.netwrote:
On Oct 9, 8:56 am, "terminator(jam)" <farid.mehr...@gmail.comwrote:


consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish
the last line of output may repeat based on how the result is
stored(rvo) or not.
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo'

The C++ Standard already allows the "(Named) Return Value
Optimization" (NRVO or RVO for short). The optimization allows (under
certain conditions) the compiler to construct the result of a function
call "in place" - that is, directly in the object initialized with the
function call result.

So, to take advantage of this optimization, a program should use the
result of a function call to initialize an object, instead of
assigning the function result to an existing object.

For example:

#include <iostream>

using std::cout;

struct memory_pig
{ // a really large type:
memory_pig()
{
cout << "mem pig default\n";
}
memory_pig(memory_pig const&)
{
cout << "mem pig copy\n";
}
~memory_pig()
{
cout << "mem pig finish\n";
}
};

memory_pig foo()
{
memory_pig result;
// ...
return result;
}

int main()
{
memory_pig m1 = foo();
memory_pig m2 = foo();
memory_pig m3 = foo();
}

I compiled the above program twice, once with and once without NRVO.
The output of both programs is shown in the two columns below. As this
comparison shows, NRVO can be a particular effective optimization -
even for a small C++ program like the one used in this example.

Program Output

Without NRVO: With NRVO:

mem pig default mem pig default
mem pig copy mem pig default
mem pig finish mem pig default
mem pig copy mem pig finish
mem pig finish mem pig finish
mem pig default mem pig finish
mem pig copy
mem pig finish
mem pig copy
mem pig finish
mem pig default
mem pig copy
mem pig finish
mem pig copy
mem pig finish
mem pig finish
mem pig finish
mem pig finish
I knew about RVO but not NRVO(that is what I am talking about).Is NRVO
standard behavoir or unspecified?
At least my compiler does not perform the NRVO.

thanx,
FM.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 14 '07 #9
On 2007-10-14 21:19, terminator wrote:
On Oct 14, 11:08 am, Greg Herlihy <gre...@pacbell.netwrote:
>On Oct 9, 8:56 am, "terminator(jam)" <farid.mehr...@gmail.comwrote:


consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish
the last line of output may repeat based on how the result is
stored(rvo) or not.
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo'

The C++ Standard already allows the "(Named) Return Value
Optimization" (NRVO or RVO for short). The optimization allows (under
certain conditions) the compiler to construct the result of a function
call "in place" - that is, directly in the object initialized with the
function call result.

So, to take advantage of this optimization, a program should use the
result of a function call to initialize an object, instead of
assigning the function result to an existing object.

For example:

#include <iostream>

using std::cout;

struct memory_pig
{ // a really large type:
memory_pig()
{
cout << "mem pig default\n";
}
memory_pig(memory_pig const&)
{
cout << "mem pig copy\n";
}
~memory_pig()
{
cout << "mem pig finish\n";
}
};

memory_pig foo()
{
memory_pig result;
// ...
return result;
}

int main()
{
memory_pig m1 = foo();
memory_pig m2 = foo();
memory_pig m3 = foo();
}

I compiled the above program twice, once with and once without NRVO.
The output of both programs is shown in the two columns below. As this
comparison shows, NRVO can be a particular effective optimization -
even for a small C++ program like the one used in this example.
>>
I knew about RVO but not NRVO(that is what I am talking about).Is NRVO
standard behavoir or unspecified?
At least my compiler does not perform the NRVO.
The standard allows this optimisation, but it does not require it (see
section 12.8 paragraph 15). I think that most newer compilers support
it, but you might have to turn up the optimisation level a bit.

One important thing to remember is that when NRVO is in use the
destructor will not be called for the local object, nor will the copy-
constructor for the non-local object (m1 to m3 in the code above) be
called. Thus you should not depend on any side effects that the copy-
constructor or destructor might have.

--
Erik Wikström

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 14 '07 #10
On Oct 14, 10:00 pm, Erik-wikst...@telia.com (Erik Wikström) wrote:
On 2007-10-14 21:19, terminator wrote:


On Oct 14, 11:08 am, Greg Herlihy <gre...@pacbell.netwrote:
On Oct 9, 8:56 am, "terminator(jam)" <farid.mehr...@gmail.comwrote:
consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish
the last line of output may repeat based on how the result is
stored(rvo) or not.
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo'
The C++ Standard already allows the "(Named) Return Value
Optimization" (NRVO or RVO for short). The optimization allows (under
certain conditions) the compiler to construct the result of a function
call "in place" - that is, directly in the object initialized with the
function call result.
So, to take advantage of this optimization, a program should use the
result of a function call to initialize an object, instead of
assigning the function result to an existing object.
For example:
#include <iostream>
using std::cout;
struct memory_pig
{ // a really large type:
memory_pig()
{
cout << "mem pig default\n";
}
memory_pig(memory_pig const&)
{
cout << "mem pig copy\n";
}
~memory_pig()
{
cout << "mem pig finish\n";
}
};
memory_pig foo()
{
memory_pig result;
// ...
return result;
}
int main()
{
memory_pig m1 = foo();
memory_pig m2 = foo();
memory_pig m3 = foo();
}
I compiled the above program twice, once with and once without NRVO.
The output of both programs is shown in the two columns below. As this
comparison shows, NRVO can be a particular effective optimization -
even for a small C++ program like the one used in this example.
I knew about RVO but not NRVO(that is what I am talking about).Is NRVO
standard behavoir or unspecified?
At least my compiler does not perform the NRVO.

The standard allows this optimisation, but it does not require it (see
section 12.8 paragraph 15). I think that most newer compilers support
it, but you might have to turn up the optimisation level a bit.

One important thing to remember is that when NRVO is in use the
destructor will not be called for the local object, nor will the copy-
constructor for the non-local object (m1 to m3 in the code above) be
called. Thus you should not depend on any side effects that the copy-
constructor or destructor might have.
prior to return and after return are two different case to me:I mean
before return even move should be disabled ,while after the return
either of move/copy must perform .

regards,
FM.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 15 '07 #11

===================================== MODERATOR'S COMMENT:

Please trim unnecessary material when replying.
===================================== END OF MODERATOR'S COMMENT
On 2007-10-15 17:52, terminator(jam) wrote:
On Oct 14, 10:00 pm, Erik-wikst...@telia.com (Erik Wikström) wrote:
>On 2007-10-14 21:19, terminator wrote:


On Oct 14, 11:08 am, Greg Herlihy <gre...@pacbell.netwrote:
On Oct 9, 8:56 am, "terminator(jam)" <farid.mehr...@gmail.comwrote:
consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish
the last line of output may repeat based on how the result is
stored(rvo) or not.
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo'
>The C++ Standard already allows the "(Named) Return Value
Optimization" (NRVO or RVO for short). The optimization allows (under
certain conditions) the compiler to construct the result of a function
call "in place" - that is, directly in the object initialized with the
function call result.
>So, to take advantage of this optimization, a program should use the
result of a function call to initialize an object, instead of
assigning the function result to an existing object.
>For example:
> #include <iostream>
> using std::cout;
> struct memory_pig
{ // a really large type:
memory_pig()
{
cout << "mem pig default\n";
}
memory_pig(memory_pig const&)
{
cout << "mem pig copy\n";
}
~memory_pig()
{
cout << "mem pig finish\n";
}
};
> memory_pig foo()
{
memory_pig result;
// ...
return result;
}
> int main()
{
memory_pig m1 = foo();
memory_pig m2 = foo();
memory_pig m3 = foo();
}
>I compiled the above program twice, once with and once without NRVO.
The output of both programs is shown in the two columns below. As this
comparison shows, NRVO can be a particular effective optimization -
even for a small C++ program like the one used in this example.
I knew about RVO but not NRVO(that is what I am talking about).Is NRVO
standard behavoir or unspecified?
At least my compiler does not perform the NRVO.

The standard allows this optimisation, but it does not require it (see
section 12.8 paragraph 15). I think that most newer compilers support
it, but you might have to turn up the optimisation level a bit.

One important thing to remember is that when NRVO is in use the
destructor will not be called for the local object, nor will the copy-
constructor for the non-local object (m1 to m3 in the code above) be
called. Thus you should not depend on any side effects that the copy-
constructor or destructor might have.

prior to return and after return are two different case to me:I mean
before return even move should be disabled ,while after the return
either of move/copy must perform .
Sorry, but you lost me there, what move? Of what to where?

--
Erik Wikström

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 15 '07 #12
On Oct 9, 7:56 pm, "terminator(jam)" <farid.mehr...@gmail.comwrote:
consider:

struct memory_pig{//a really large type:

memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};

memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};

~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};

//etc...

};///struct memory_pig

memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;

};

any time 'foo' is called the output will contain the following
sequence:

mem pig default
mem pig copy
mem pig finish
It won't. It certainly won't do that with the example given, since
there's no clear association in it between the copy constructor and
the assignment operator (considering that the latter isn't even
defined). Assuming there was such an association, though, I'd rather
expect to see:

mem pig default
mem pig copy // first assignment
mem pig copy // second assignment
mem pig finish

Which is correct and fine - if you have explicitly written the
assignment operator twice, then surely you want the associated side-
effects? And if you do not, then perhaps you shouldn't have written it
that way.
that is you can refrence the returned object inside the function and
decrease the overhead for copying large objects.C++ lacks such syntax
and IMHO we should be able to mark the result object as referencing
the actual return so that there is no need for the extra copy
construction
This is precisely what NRVO does.

I have a feeling that you're confusing assignment with initialization
in this case. Assignment operator always applies to an already-
initialized object - the compiler cannot elide the initialization
except for the trivial cases (e.g. POD types), which is why operator=
still results in unnecessary copying even when the compiler implements
NRVO. It's not a problem with NRVO though - it's because assignment is
used where just initialization would suffice. Direct initialization is
still more efficient then assignment-following-initialization, even
with the move semantics of C++0x.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 16 '07 #13
On Oct 15, 8:35 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
===================================== MODERATOR'S COMMENT:

Please trim unnecessary material when replying.

===================================== END OF MODERATOR'S COMMENT
On 2007-10-15 17:52, terminator(jam) wrote:


On Oct 14, 10:00 pm, Erik-wikst...@telia.com (Erik Wikström) wrote:
On 2007-10-14 21:19, terminator wrote:
On Oct 14, 11:08 am, Greg Herlihy <gre...@pacbell.netwrote:
On Oct 9, 8:56 am, "terminator(jam)" <farid.mehr...@gmail.comwrote:
consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish
the last line of output may repeat based on how the result is
stored(rvo) or not.
So,two objects of a large type will be constructed and at least one is
destructed on every call to 'foo'
The C++ Standard already allows the "(Named) Return Value
Optimization" (NRVO or RVO for short). The optimization allows (under
certain conditions) the compiler to construct the result of a function
call "in place" - that is, directly in the object initialized with the
function call result.
So, to take advantage of this optimization, a program should use the
result of a function call to initialize an object, instead of
assigning the function result to an existing object.
For example:
#include <iostream>
using std::cout;
struct memory_pig
{ // a really large type:
memory_pig()
{
cout << "mem pig default\n";
}
memory_pig(memory_pig const&)
{
cout << "mem pig copy\n";
}
~memory_pig()
{
cout << "mem pig finish\n";
}
};
memory_pig foo()
{
memory_pig result;
// ...
return result;
}
int main()
{
memory_pig m1 = foo();
memory_pig m2 = foo();
memory_pig m3 = foo();
}
I compiled the above program twice, once with and once without NRVO.
The output of both programs is shown in the two columns below. As this
comparison shows, NRVO can be a particular effective optimization -
even for a small C++ program like the one used in this example.
I knew about RVO but not NRVO(that is what I am talking about).Is NRVO
standard behavoir or unspecified?
At least my compiler does not perform the NRVO.
The standard allows this optimisation, but it does not require it (see
section 12.8 paragraph 15). I think that most newer compilers support
it, but you might have to turn up the optimisation level a bit.
One important thing to remember is that when NRVO is in use the
destructor will not be called for the local object, nor will the copy-
constructor for the non-local object (m1 to m3 in the code above) be
called. Thus you should not depend on any side effects that the copy-
constructor or destructor might have.
prior to return and after return are two different case to me:I mean
before return even move should be disabled ,while after the return
either of move/copy must perform .

Sorry, but you lost me there, what move? Of what to where?
Move ctor of course.

regards,
FM.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 16 '07 #14
On Oct 16, 8:44 am, int...@gmail.com wrote:
On Oct 9, 7:56 pm, "terminator(jam)" <farid.mehr...@gmail.comwrote:


consider:
struct memory_pig{//a really large type:
memory_pig(){
std::cout<<"mem pig default\n";
//etc...
};
memory_pig(memory_pig const&){
std::cout<<"mem pig copy\n";
//etc...
};
~memory_pig(){
std::cout<<"mem pig finish\n";
//etc...
};
//etc...
};///struct memory_pig
memory_pig foo(){
memory_pig result;
result=something;
//etc...
result=something_else;
return result;
};
any time 'foo' is called the output will contain the following
sequence:
mem pig default
mem pig copy
mem pig finish

It won't. It certainly won't do that with the example given, since
there's no clear association in it between the copy constructor and
the assignment operator (considering that the latter isn't even
defined). Assuming there was such an association, though, I'd rather
expect to see:

mem pig default
mem pig copy // first assignment
mem pig copy // second assignment
mem pig finish
As I wrote before its just an illustration and I did not mean any
assignment,replace it with any function( eg. modify(result) ;).
Which is correct and fine - if you have explicitly written the
assignment operator twice, then surely you want the associated side-
effects? And if you do not, then perhaps you shouldn't have written it
that way.
that is you can refrence the returned object inside the function and
decrease the overhead for copying large objects.C++ lacks such syntax
and IMHO we should be able to mark the result object as referencing
the actual return so that there is no need for the extra copy
construction

This is precisely what NRVO does.
I was certain about the NRVO by the time I started the post.However
NRVO is a compiler option(ugly!!!) not a demand .With NRVO we have two
distinct phases optimize simultaniously : prior to return inside the
callee and after that inside the caller:

A foo(){
A ret;//this will be return under any conditions.
//....
return ret;//pre return :no copy/move
};
class A a=foo();//after return : copy/move to a

I have a feeling that you're confusing assignment with initialization
in this case. Assignment operator always applies to an already-
initialized object - the compiler cannot elide the initialization
except for the trivial cases (e.g. POD types), which is why operator=
still results in unnecessary copying even when the compiler implements
NRVO. It's not a problem with NRVO though - it's because assignment is
used where just initialization would suffice. Direct initialization is
still more efficient then assignment-following-initialization, even
with the move semantics of C++0x.
Everybody makes mistakes while learning , but confusing assignment
with copy certainly has never been the mistake I can make.

regards,
FM

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 16 '07 #15
On 2007-10-16 19:55, terminator(jam) wrote:
On Oct 15, 8:35 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2007-10-15 17:52, terminator(jam) wrote:
On Oct 14, 10:00 pm, Erik-wikst...@telia.com (Erik Wikström) wrote:
On 2007-10-14 21:19, terminator wrote:
On Oct 14, 11:08 am, Greg Herlihy <gre...@pacbell.netwrote:
On Oct 9, 8:56 am, "terminator(jam)" <farid.mehr...@gmail.comwrote:
>The C++ Standard already allows the "(Named) Return Value
Optimization" (NRVO or RVO for short). The optimization allows (under
certain conditions) the compiler to construct the result of a function
call "in place" - that is, directly in the object initialized with the
function call result.
>So, to take advantage of this optimization, a program should usethe
result of a function call to initialize an object, instead of
assigning the function result to an existing object.
>For example:
> #include <iostream>
> using std::cout;
> struct memory_pig
{ // a really large type:
memory_pig()
{
cout << "mem pig default\n";
}
memory_pig(memory_pig const&)
{
cout << "mem pig copy\n";
}
~memory_pig()
{
cout << "mem pig finish\n";
}
};
> memory_pig foo()
{
memory_pig result;
// ...
return result;
}
> int main()
{
memory_pig m1 = foo();
memory_pig m2 = foo();
memory_pig m3 = foo();
}
>I compiled the above program twice, once with and once without NRVO.
The output of both programs is shown in the two columns below. As this
comparison shows, NRVO can be a particular effective optimization -
even for a small C++ program like the one used in this example.
I knew about RVO but not NRVO(that is what I am talking about).IsNRVO
standard behavoir or unspecified?
At least my compiler does not perform the NRVO.
>The standard allows this optimisation, but it does not require it (see
section 12.8 paragraph 15). I think that most newer compilers support
it, but you might have to turn up the optimisation level a bit.
>One important thing to remember is that when NRVO is in use the
destructor will not be called for the local object, nor will the copy-
constructor for the non-local object (m1 to m3 in the code above) be
called. Thus you should not depend on any side effects that the copy-
constructor or destructor might have.
prior to return and after return are two different case to me:I mean
before return even move should be disabled ,while after the return
either of move/copy must perform .

Sorry, but you lost me there, what move? Of what to where?
Move ctor of course.
Sorry, but I still do not understand. What do you mean with RNVO should
be disabled before return but not after? It is something that is
performed *during* return.

--
Erik Wikström

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 16 '07 #16
On Oct 16, 9:37 pm, Erik-wikst...@telia.com (Erik Wikström) wrote:
On 2007-10-16 19:55, terminator(jam) wrote:


On Oct 15, 8:35 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-10-15 17:52, terminator(jam) wrote:
On Oct 14, 10:00 pm, Erik-wikst...@telia.com (Erik Wikström) wrote:
On 2007-10-14 21:19, terminator wrote:
On Oct 14, 11:08 am, Greg Herlihy <gre...@pacbell.netwrote:
On Oct 9, 8:56 am, "terminator(jam)" <farid.mehr...@gmail.comwrote:
The C++ Standard already allows the "(Named) Return Value
Optimization" (NRVO or RVO for short). The optimization allows (under
certain conditions) the compiler to construct the result of a function
call "in place" - that is, directly in the object initialized with the
function call result.
So, to take advantage of this optimization, a program should use the
result of a function call to initialize an object, instead of
assigning the function result to an existing object.
For example:
#include <iostream>
using std::cout;
struct memory_pig
{ // a really large type:
memory_pig()
{
cout << "mem pig default\n";
}
memory_pig(memory_pig const&)
{
cout << "mem pig copy\n";
}
~memory_pig()
{
cout << "mem pig finish\n";
}
};
memory_pig foo()
{
memory_pig result;
// ...
return result;
}
int main()
{
memory_pig m1 = foo();
memory_pig m2 = foo();
memory_pig m3 = foo();
}
I compiled the above program twice, once with and once without NRVO.
The output of both programs is shown in the two columns below. As this
comparison shows, NRVO can be a particular effective optimization -
even for a small C++ program like the one used in this example.
I knew about RVO but not NRVO(that is what I am talking about).Is NRVO
standard behavoir or unspecified?
At least my compiler does not perform the NRVO.
The standard allows this optimisation, but it does not require it (see
section 12.8 paragraph 15). I think that most newer compilers support
it, but you might have to turn up the optimisation level a bit.
One important thing to remember is that when NRVO is in use the
destructor will not be called for the local object, nor will the copy-
constructor for the non-local object (m1 to m3 in the code above) be
called. Thus you should not depend on any side effects that the copy-
constructor or destructor might have.
prior to return and after return are two different case to me:I mean
before return even move should be disabled ,while after the return
either of move/copy must perform .
Sorry, but you lost me there, what move? Of what to where?
Move ctor of course.

Sorry, but I still do not understand. What do you mean with RNVO should
be disabled before return but not after? It is something that is
performed *during* return.
I mean the whole concept of optimization(rvo,nrvo,etc). IMHO:
If a function always returns the same local object the returned object
must be the local object itself rather than a copy/move version of the
local.
If a function returns one of its parameter values returned object is
copy/moved from that parameter because a change in location of the
object is almost inevitable.
If an object is constructed with an rvalue it should be copy/moved.

regards,
FM

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 17 '07 #17
On 16 Oct, 23:26, "terminator(jam)" <farid.mehr...@gmail.comwrote:
A foo(){
A ret;//this will be return under any conditions.
//....
return ret;//pre return :no copy/move};

class A a=foo();//after return : copy/move to a
This is not the case. If the compiler correctly implements NRVO, the
example above will result in a single construction of A using the
default constructor, and then a subsequent destruction. No copies or
moves are made at any point.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 17 '07 #18
On 2007-10-17 17:53, terminator(jam) wrote:
On Oct 16, 9:37 pm, Erik-wikst...@telia.com (Erik Wikström) wrote:
>On 2007-10-16 19:55, terminator(jam) wrote:
On Oct 15, 8:35 pm, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-10-15 17:52, terminator(jam) wrote:
On Oct 14, 10:00 pm, Erik-wikst...@telia.com (Erik Wikström)wrote:
On 2007-10-14 21:19, terminator wrote:
On Oct 14, 11:08 am, Greg Herlihy <gre...@pacbell.netwrote:
On Oct 9, 8:56 am, "terminator(jam)" <farid.mehr...@gmail.comwrote:
The C++ Standard already allows the "(Named) Return Value
Optimization" (NRVO or RVO for short). The optimization allows (under
certain conditions) the compiler to construct the result of afunction
call "in place" - that is, directly in the object initializedwith the
function call result.
>So, to take advantage of this optimization, a program should use the
result of a function call to initialize an object, instead of
assigning the function result to an existing object.
>For example:
> #include <iostream>
> using std::cout;
> struct memory_pig
{ // a really large type:
memory_pig()
{
cout << "mem pig default\n";
}
memory_pig(memory_pig const&)
{
cout << "mem pig copy\n";
}
~memory_pig()
{
cout << "mem pig finish\n";
}
};
> memory_pig foo()
{
memory_pig result;
// ...
return result;
}
> int main()
{
memory_pig m1 = foo();
memory_pig m2 = foo();
memory_pig m3 = foo();
}
>I compiled the above program twice, once with and once without NRVO.
The output of both programs is shown in the two columns below.. As this
comparison shows, NRVO can be a particular effective optimization -
even for a small C++ program like the one used in this example.
I knew about RVO but not NRVO(that is what I am talking about)..Is NRVO
standard behavoir or unspecified?
At least my compiler does not perform the NRVO.
>The standard allows this optimisation, but it does not require it (see
section 12.8 paragraph 15). I think that most newer compilers support
it, but you might have to turn up the optimisation level a bit.
>One important thing to remember is that when NRVO is in use the
destructor will not be called for the local object, nor will thecopy-
constructor for the non-local object (m1 to m3 in the code above) be
called. Thus you should not depend on any side effects that the copy-
constructor or destructor might have.
prior to return and after return are two different case to me:I mean
before return even move should be disabled ,while after the return
either of move/copy must perform .
>Sorry, but you lost me there, what move? Of what to where?
Move ctor of course.

Sorry, but I still do not understand. What do you mean with RNVO should
be disabled before return but not after? It is something that is
performed *during* return.
I mean the whole concept of optimization(rvo,nrvo,etc). IMHO:
If a function always returns the same local object the returned object
must be the local object itself
You mean for a function such as

foo bar()
{
foo f;
return f;
}

NRVO should be used? That is (to my knowledge) the case if NRVO is
enabled in the compiler.
rather than a copy/move version of the local.
What is the difference between copy and move? I would say that NRVO is
move, since the object created in the function is moved to the
"surrounding" context/scope instead of being used as the basis of a copy.
If a function returns one of its parameter values returned object is
copy/moved from that parameter because a change in location of the
object is almost inevitable.
Assuming that you by copy/move mean that the object in the function is
being copied to the surrounding scope, did you mean that something like

foo bar(bool b)
{
foo f1, f2;
if (b)
return f1;
else
return f2;
}

should not use NRVO? Again, to my knowledge that is the case, since the
compiler can not predict which of the objects will be returned so a copy
is necessary.
If an object is constructed with an rvalue it should be copy/moved.
You mean something similar to

foo bar()
{
foo f1, f2;
return f1 + f2;
}

In that case NRVO could be used depending on whether the compiler knows
which object will be returned or not. So the above could utilise NRVO
but something like

foo bar(bool b)
{
foo f1, f2, f3;
if (b)
return f1 + f2;
else
return f2 + f3;
}

could not.

If the above is not what you meant, then I am sorry to have failed to
understand you. Perhaps you could try to rephrase the question or use
simple code examples.

--
Erik Wikström

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:st*****@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Oct 17 '07 #19

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

Similar topics

20
by: Jakob Bieling | last post by:
Hi! I am using VC++ 7.1 and have a question about return value optimization. Consider the following code: #include <list> #include <string> struct test {
25
by: cppaddict | last post by:
I'd like to know what goes on under the hood when methods return objects. Eg, I have a simple Point class with two members _x and _y. It's constructor, copy constructor, assignment operator and...
14
by: Gama Franco | last post by:
Hi, I'm designing an interface for a shared library, and I would like to know if there is a standard about how to return an object to the user. I will use exceptions to report errors, so there...
29
by: pmatos | last post by:
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> *...
5
by: Bert Jansen | last post by:
There seems to be a bug in de VS .net C++ compiler (optimization) when using inline functions that return static data. The following code demonstrates this (Win32 console app with ATL support): ...
15
by: Andrew Brampton | last post by:
Hi, This may sound a odd question, but I wanted to know how you return a list of data from a function. These are some of the ways I know how, and I was wondering which method you normally use....
2
by: Eric Lilja | last post by:
Hello, consider this complete program: #include <iostream> #include <string> using std::cout; using std::endl; using std::string; class Hanna {
32
by: Axel Bock | last post by:
Hi all, I am trying to get my head around what happens if I return a class object from a function. It seems C++ (MinGW) does not invoke the copy constructor if I do something like this: ...
10
by: SzH | last post by:
The code below demonstrates that the copy constructor of moo is not called on the first line of main. In spite of this, g++ (version 4.1.2) refuses to compile it if I make the copy constructor...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.