For instance, if I have this code:
class SomeDataProcessor
{
public:
bool calc(const SomeData & d1, const SomeData & d2) const;
private:
//Some n
Yes, absolutely.
Compilers do this all the time, and more.
For example, if all your function did were return true
, and its definition were visible to the compiler at the callsite, the entire function call would probably be elided, resulting in just:
someObscureFunction(true, true);
A program for which the compiler has sufficient information may be "optimised" from a quite complex chain of tasks down to perhaps one or two instructions. Now, actually operating on member variables is pushing the optimiser to its limit to some degree, but if the variables are private
, are given a known initial value, and are not mutated by any other member function, I don't see why a compiler couldn't just inline its known value if it wanted to. Compilers are very, very smart.
People think that a compiled program is a one-to-one mapping of lines in your source code, but this is almost never true. The entire purpose of C++ is that it is an abstraction of what your computer's actually going to be doing when it runs your program.
GCC has the pure
attribute (used as __attribute__((pure))
) for functions which tells the compiler that redundant calls can be eliminated. It's used e.g. on strlen
.
I'm not aware of any compiler doing this automatically, especially considering the fact that the functions to be called may not be available in source form, and the object file formats contain no metadata about whether a function is pure or not.
Yes, modern C compilers can elide redundant function calls if and only if they can prove that such an optimization behaves as-if the original program semantics were followed. For example, that means means they could eliminate multiple calls to the same function with the same arguments, if the function has no side-effects and if its return value depends only on the arguments.
Now, you asked specifically about const
- this is mostly useful to the developer, and not the coder. A const
function is a hints that the method doesn't modify the object it is called on, and const
arguments are hints that the arguments are not modified. However, the function may (legally1) cast away the const
-ness of the this
pointer or of its arguments. So the compiler can't rely on it.
Furthermore, even if const
objects passed to a function really were never modified within that function, and const
functions never modified the receiver object, the method could easily rely on mutable global data (and could mutate such data). Consider, for example, a function that returns the current time, or which increments a global counter.
So the const
declarations help the programmer, not the compiler2.
However, the compiler might be able to use other tricks to prove the calls are redundant:
const
function attributes which inform gcc
that the functions has no side effects, and depend only on their parameters (and on global variables, in the case of pure
).1 Usually, as long as the object wasn't originally defined as const
.
2 There is at one sense in which const
definitions do help the compiler: they can put global objects defined as const
into a read-only section of the executable (if such a feature exists) and also combine such objects when they are equal (e.g., identical string constants).
No, the compiler is not allowed to do that in this case. The const
only means you do not change the state of the object the method belongs to. However, invoking this method multiple times with the same input parameters might give different results. For example, think of a method that produces a random result.
No, given the shown code, the compiler cannot guarantee that the proposed optimization will have no observable differences, and no modern compiler will be able to optimize away the second function call.
A very simple example: this class method might use a random number generator, and save the result in some private buffer, that some other part of the code reads later on. Obviously, eliminating a function call now results in fewer randomly-generated values being placed in that buffer.
In other words, just because a class method is const
does not mean that it has no observable side effects when it's called.