A: 

I doubt most compilers could do that if they were in different compilation objects (ie. different files). Maybe if they were both in the same file, they could.

Paul Tomblin
Agreed. Enabling "whole program optimization" might make it happen as well, provided that the return value was never used on any invocation.
Drew Hall
@Drew, is "whole program optimization" a vc++ thing, because I can't imagine it being possible in a Linux/Unix environment.
Paul Tomblin
Rumours of efforts towards it for example here: http://www.airs.com/blog/archives/100
Steve Jessop
@Paul, it is possible, but you basically tell GCC to compile *all* your source files and give it the -fwhole-program flag. It can easily use 1.5 GB RAM and more.
Zan Lynx
+1  A: 

They most likely will if the optimization level causes them to inline the code. If not, they would have to generate two different translations of the same code to make it work, which could open up a lot of edge case problems.

kasperjj
+1  A: 

The linker can take care of this sort of thing, even if the original caller and called are in different compilation units.

If you have a good reason to be concerned about the CPU load dedicated to a method call (premature optimization is the root of all evil,) you might consider the many inlining options available to you, including (gasp!) a macro.

Do you REALLY need to optimize at this level?

The linker can NOT do any optimization like that. The called function can not know if the result is being used or not and thus must generate it. Only the compiler has enough knowledge to even get close to optimiszing this away and this will only happen if everything is inlined.
Martin York
I think he may be talking about linkers like Microsoft's, which I believe takes an intermediate representation of all the objects and performs another compilation step in order to do inter-module optimization.
Zan Lynx
+5  A: 

If the ReturnValue class has a non-trivial copy constructor, the compiler must not eliminate the call to the copy constructor - it is mandated by the language that it is invoked.

If the copy constructor is inline, the compiler might be able to inline the call, which in turn might cause a elimination of much of its code (also depending on whether FunctionThatAltersMembersAndNeverFails is inline).

Martin v. Löwis
Not so. In the specific case of temporaries, the compiler has explicit permission to directly construct the object in its destination instead of copying it (see ISO 14882 §12.2). If the intermediate object had a name, you'd be correct.
puetzk
In the given example, how can it not invoke the copy constructor (assuming the type of successfulResultObject is already ReturnValue)? "Direct copying", in this specific case, still involves the copy constructor.
Martin v. Löwis
A: 

There is a pretty good chance that a peephole optimizer will catch this. Many (most?) compilers implement one, so the answer is probably "yes".

As others have notes this is not a trivial question at the AST rewriting level.


Peephole optimizers work on a representation of the code at a level equivalent to assembly language (but before generation of actual machine code). There is a chance to notice the load of the return value into a register followed by a overwrite with no intermediate read, and just remove the load. This is done on a case by case basis.

dmckee
A: 

If return value is an int and you return 0 (as in the edited question), then this may get optimized away.

You have to look at the underlying assembly. If the function is not inlined then the underlying assembly will execute a mov eax, 0 (or xor eax, eax) to set eax (which is usually used for integer return values) to 0. If the function is inlined, this will certainly get optimized away.

But this senario isn't too useful if you're worried about what happens when you return objects larger than 32-bits. You'll need to refer to the answers to the unedit question, which paint a pretty good picture: If everything is inlined then most of it will be optimized out. If it is not inlined, then the functions must be called even if they don't really do anything, and that includes the constructor of an object (since the compiler doesn't know whether the constructor modified global variables or did something else weird).

SoapBox