const
is pointless when the argument is passed by value since you will
not be modifying the caller's object.
Wrong.
It's about self-documenting your code and your assumptions.
If your code has many people working on it and your functions are non-trivial then you should mark const
any and everything that you can. When writing industrial-strength code, you should always assume that your coworkers are psychopaths trying to get you any way they can (especially since it's often yourself in the future).
Besides, as somebody mentioned earlier, it might help the compiler optimize things a bit (though it's a long shot).
There are two main considerations. One is the expense of copying the passed object and the second is the assumptions that the compiler can make when the object is a a local object.
E.g. In the first form, in the body of f
it cannot be assumed that a
and b
don't reference the same object; so the value of a
must be re-read after any write to b
, just in case. In the second form, a
cannot be changed via a write to b
, as it is local to the function, so these re-reads are unnecessary.
void f(const Obj& a, Obj& b)
{
// a and b could reference the same object
}
void f(Obj a, Obj& b)
{
// a is local, b cannot be a reference to a
}
E.g.: In the first example, the compiler may be able to assume that the value of a local object doesn't change when an unrelated call is made. Without information about h
, the compiler may not know whether an object that that function has a reference to (via a reference parameter) isn't changed by h
. For example, that object might be part of a global state which is modified by h
.
void g(const Obj& a)
{
// ...
h(); // the value of a might change
// ...
}
void g(Obj a)
{
// ...
h(); // the value of a is unlikely to change
// ...
}
Unfortunately, this example isn't cast iron. It is possible to write a class that, say, adds a pointer to itself to a global state object in its constructor, so that even a local object of class type might be altered by a global function call. Despite this, there are still potentially more opportunities for valid optimizations for local objects as they can't be aliased directly by references passed in, or other pre-existing objects.
Passing a parameter by const
reference should be chosen where the semantics of references are actually required, or as a performance improvement only if the cost of potential aliasing would be outweighed by the expense of copying the parameter.
Best Answer
From the caller's perspective, both the first and the second form are the same.
Since the integers are passed by value, even if the function modifies
a
andb
, the modified values are copies of the original and won't be visible to the caller.However, from the function implementer's perspective there's a difference. In fact, in the second form:
you will get a compiler error if you try to modify the values of
a
andb
inside the function's body, as they are marked asconst
.Instead, you can change those values if you omit the
const
.Again, those modifications will not be visible to the caller.