Ultimate Efficiency

O

Old Wolf

"temporary" means an object without a name.

Yes there is. The call to monkey() returns a temporary variable of type int.
Then notemp is initialized from this temporary int, and then the temporary
int is destroyed.
Just check out assembly code created from compiler.
How and where do you think temporary variable is created in
called function?

Probably your compiler will use a register for the temporary int.
monkey() would assign 22 to this register, and then the calling function
would copy the value from that register into the memory location of notemp.

Of course, the compiler could optimise this out entirely, or in fact use
any other assembly instructions that it likes. That doesn't change
what is happening theoretically.
 
B

Branimir Maksimovic

Old Wolf said:
Yes there is. The call to monkey() returns a temporary variable of type int.
Then notemp is initialized from this temporary int, and then the temporary
int is destroyed.

I don't think so:
"
[stmt.return] 6.6.3 The return statement

1 A function returns to its caller by the return statement.

2 A return statement without an expression can be used only in functions
that do not return a value, that is, a function with the return type void, a
constructor (12.1), or a destructor (12.4). A return statement with an
expression of nonvoid type can be used only in functions returning a value;
the value of the expression is returned to the caller of the function.
The expression is implicitly converted to the return type of the function
in which it appears. A return statement can involve the construction and
copy of a temporary object
"

As you can see this clearly proves my point.
return statement always returns value, not temporary variable.
It *can* involve the construction and copy of tmp object.
So there is not *must*.
Probably your compiler will use a register for the temporary int.
monkey() would assign 22 to this register, and then the calling function
would copy the value from that register into the memory location of notemp.

Of course, the compiler could optimise this out entirely, or in fact use
any other assembly instructions that it likes. That doesn't change
what is happening theoretically.

T func()
{
T tmp;
// ....
return t;
}

T x = func();

In case that x cannot fit in register,
implementation can just pass address of x to func, which will construct
tmp in place of it, effectively returning nothing, because standard says
so.
In case that x can fit in register,
implementation can just assign *value* returned from function.

Theoretically func returns value, not temporary object, so everything is
allowed.

Greetings, Bane.

P.S.
me advocate ? nooooooo :(
 
O

Old Wolf

[I won't reply to the first half of the post, except to say that I think
we are saying the same thing: "The compiler can do X" and "The compiler
always does X and sometimes optimises it out", surely amount to the
same thing]
T func()
{
T tmp;
// ....
return t;
}

T x = func();

In case that x cannot fit in register,
implementation can just pass address of x to func, which will construct
tmp in place of it, effectively returning nothing, because standard says
so.
In case that x can fit in register,
implementation can just assign *value* returned from function.

This is called NRVO (named return value optimisation). As you mentioned,
the compiler *can* do this , but it does not have to. A standards-
conforming compiler could call one default constructor and two
copy constructors and two destructors, for the above example.
Note that the above code *must not* compile on a standards-conforming
compiler if there is not an accessible copy constructor for T.
Theoretically func returns value, not temporary object, so everything is
allowed.

A temporary object *is* a value (or, pedantically, the value of the
[rvalue] expression "func()" is a temporary object of type T).
For example, if in the above code 'func' was in a different
translation unit, then it obviously couldn't perform RVO, eg. if
the caller went:
func().foo();
 
P

Peter van Merkerk

JKop said:
Branimir Maksimovic posted:


I don't know assembly!

If you are really so concerned about efficiency you should learn it.
Reading the assembler code generated by the compiler can be really
instructive. It will learn you what your compiler can and cannot
optimize. With that knowledge you can avoid pointless optimization
efforts that often do more harm than good (in many ways). Optimization
attempts based on just assumptions are almost never a good idea. I have
seen too many times people writing very ugly code in the assumption that
it will run faster, while often it makes no differences at all or is
even slower than the cleanly coded version.

BTW. if you only want to be able to read assembly code it is really not
that hard; it is a lot simpler than the C++ language. The effort may be
worthwhile if your intention is to write high performance code. But if
you are only interested in doing GUI or database stuff...don't bother.
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top