In the following C++ functions:
void MyFunction(int age, House &purchased_house)
{
...
}
void MyFunction(const int age, House &purchased_house)
One benefit of using const
is that you cannot accidentally change the value of age
in the middle of MyFunction
(in the event you forgot it was not pass by reference). One "disadvantage" is that you can't recycle age
with code like foo.process(++age);
.
Well, as other have already said, from the point of view of C++ language, the above const
has no effect on function signature, i.e. the function type remains the same regardless of whether the const
is there or not. The only effect it has at the level of abstract C++ language is that you can't modify this parameter inside the function body.
However, at the lower level, the const
modifier applied to the parameter value can have some optimization benefits, given a sufficiently clever compiler. Consider two functions with the same parameter set (for simplicity)
int foo(const int a, const double b, const long c) {
/* whatever */
}
void bar(const int a, const double b, const long c) {
/* whatever */
}
Let's say somewhere in the code they are called as follows
foo(x, d, m);
bar(x, d, m);
Normally, compilers prepare stack frame with arguments before they call a function. In this case the stack will usually be prepared twice: once for each call. But a clever compiler might realize that since these functions do not change their local parameter values (declared with const
), the argument set prepared for the first call can be safely reused for the second call. Thus it can prepare the stack only once.
This is a rather rare and obscure optimization, which can only work when the definition of the function is known at the point of the call (either same translation unit, or an advanced globally-optimizing compiler), but sometimes it might be worth mentioning.
It is not correct to say that it is "worthless" or "has no effect", even though with a typical compiler this might be the case.
Another consideration that is worth mentioning is of different nature. There are coding standards out there, which require coders not to change the initial parameter values, as in "don't use parameters as ordinary local variables, parameter values should remain unchanged throughout the function". This kinda makes sense, since sometimes it makes it easier to determine what parameter values the function was originally given (while in debugger, inside the body of the function). To help enforce this coding standard, people might use const
specifiers on parameter values. Whether it is worth it or not is a different question...
I recommend reading Herb Sutter. Exceptional C++. There is a chapter "Const-Correctness".
"In fact, to the compiler, the function signature is the same whether you include this const in front of a value parameter or not."
It means that this signature
void print(int number);
is effectively the same as this:
void print(int const number);
So, to the compiler there is no difference how you declare a function. And you can't overload it by putting the const keyword in front of a pass by value parameter.
Read further, what Herb Sutter recommends:
"Avoid const pass-by-value parameters in function declarations. Still make the parameter const in the same function's definition if it won't be modified."
He recommends to avoid this:
void print(int const number);
Because that const is confusing, verbose and redundant.
But in the definition, you should do that (if you won't change the parameter):
void print(int const number)
{
// I don't want to change the number accidentally here
...
}
So, you'll be sure that even after 1000 lines of function's body you always have the number untouched. The compiler will prohibit you from passing the number as a non-const reference to another function.
You not only indicate that it will not change, it will prevent your code from thinking it can and it will be caught at compilation time.
You should use const
on a parameter if (and only if) you would use it on any other local variable that won't be modified:
const int age_last_year = age - YEAR;
It's sometimes handy to mark local variables const where possible, since it means you can look at the declaration and know that's the value, without thinking about intermediate code. You can easily change it in future (and make sure you haven't broken the code in the function, and maybe change the name of the variable if it now represents something slightly different, which is changeable, as opposed to the previous non-changing thing).
As against that, it does make the code more verbose, and in a short function it's almost always very obvious which variables change and which don't.
So, either:
void MyFunction(const int age, House &purchased_house)
{
const int age_last_year = age - YEAR;
}
or:
void MyFunction(int age, House &purchased_house)
{
int age_last_year = age - YEAR;
}
This, IMHO, is overusing. When you say 'const int age,...' what you actually say is "you can't change even the local copy inside your function". What you do is actually make the programmer code less readable by forcing him to use another local copy when he wants to change age/pass it by non-const reference.
Any programmer should be familiar with the difference between pass by reference and pass by value just as any programmer should understand 'const'.