For most simple optimizations, the compiler is good enough that you
shouldn't try to do the work for it.
The big difference between your understanding of your code and the
compiler's understanding is usually in aliasing.
In version 2, you probably know that e does not alias a or b. But the
compiler may not. So the compiler may generate less efficient code.
In version 1, the compiler knows h does not alias a or b, so it can
generate the best code.
Trying to avoid allocation of a local variable is almost always silly.
In version 1, the compiler will generally figure out that h is a
temporary value that can live entirely in a register and doesn't really
need a local variable.
"const" for local variable (your version 3) should be used to help catch
programming errors. It is almost always useless as an optimization
hint, so don't try to use it as an optimization hint.
Passing doubles by value vs. const& is a difficult question (when you're
trying to push performance to the limit). In an inline function it
usually doesn't matter and if it matters const& is usually better. But
in a non inline function, it usually matters and is very hard to predict
which will be better. Aliasing issues may be a significant reason that
value may be better than const&. I think the aliasing issues can be
managed with attributes, but I'm not certain.
If you cared about performance on a routine like this, making it inline
is more important than the details you asked about. inline is usually
viewed as a time space tradeoff, but often inline is better for time and
space. The cost of setting up the three parameters within the calling
code might match the cost of inlining the whole function, so at the
point of call, inlining might take zero net space and save time. Then
the called function itself might be omitted by the compiler or linker
saving net space. Inlining also lets the compiler look at more context
in deciding aliasing issues, etc.
Martin Ettl wrote:
#Version 1
double vFoo( const double &a, const double &b, double &e )
{
double s = a + b;
double h = s - a;
e =(s-(a-h))+(h-b);
return s;
}
#Version 2
double vFoo( const double &a, const double &b, double &e )
{
double s = a + b;
e = s - a;
e =(s-(a-e))+(e-b);
return s;
}
#Version 3
double vFoo( const double &a, const double &b, double &e )
{
const double s = a + b;
e = s - a;
e =(s-(a-e))+(e-b);
return s;
}