Any call to foo could be cached and avoided. This is allowed by the compiler (but I'm not sure if the optimization is implemented).
It does, but only in the same expression, i.e.
auto a = sin(x) * sin(x); // sin() is called only once but: auto a = sin(x); auto b = sin(x); // sin() is called again here